├── Design-Patterns-Glossary.pdf ├── Design-Patterns_Course-Notes.pdf ├── Images ├── FactoryMethodUML-ex.png ├── FactoryMethodUML.png ├── MVC.png ├── adapter-diagram-1.png ├── adapter-diagram-2.png ├── adapter-diagram-3.png ├── chainOfResponsibility-1.png ├── chainOfResponsibility-2.png ├── chainOfResponsibility-3.png ├── chainOfResponsibility-4.png ├── command-pattern-1.png ├── command-pattern-2.png ├── command-pattern-3.png ├── command-pattern-4.png ├── command-pattern-5.png ├── composite-diagram-1.png ├── composite-diagram-2.png ├── composite-diagram-3.png ├── composite-diagram-4.png ├── composite-diagram-5.png ├── decorator-adding-functionality.png ├── decorator-diagram-1.png ├── decorator-diagram-2.png ├── decorator-diagram-3.png ├── facade-1.png ├── facade-2.png ├── mediator-pattern-1.png ├── mediator-pattern-2.png ├── mediator-pattern-3.png ├── mediator-pattern-4.png ├── mediator-pattern-5.png ├── mediator-pattern-6.png ├── observe-pattern-1.png ├── observe-pattern-2.png ├── proxy-diagram-1.png ├── proxy-diagram-2.png ├── proxy-diagram-3.png ├── singleton-uml.jpg ├── state-pattern-1.png ├── state-pattern-2.png ├── state-pattern-3.png ├── template-method-pattern-1.png └── template-method-pattern-2.png ├── OOD ├── Categories-of-Objects.pdf ├── OOD-Glossary.pdf ├── Object-Oriented-Design_Course-Notes.pdf ├── README.md ├── User-Stories.pdf └── images │ ├── C.png │ ├── COBOL-Fortran.png │ ├── Pascal.png │ ├── UMLSequence-ex1.png │ ├── UMLSequence-ex2.png │ ├── UMLSequence-ex3.png │ ├── UMLState-ex.png │ ├── abstraction-ex.png │ ├── aggreg-ex.png │ ├── agile-process.png │ ├── association-ex.png │ ├── c++_java_c#.png │ ├── class-vs-interface.png │ ├── composition-ex.png │ ├── couped-ex.png │ ├── crc_bank.png │ ├── crc_card.png │ ├── crc_customer.png │ ├── encap-ex.png │ ├── example1-CM.png │ ├── example1-TD.png │ ├── generalization-ex1.png │ ├── generalization-ex2.png │ ├── generlize-exp-1.png │ ├── generlize-exp-2.png │ ├── interface-ex1.png │ ├── interface-ex2.png │ ├── misunderstanding-requirments.png │ ├── multi-inher-ex.png │ ├── seperation-of-concerns.png │ ├── smartphone-ex1.png │ └── smartphone-ex2.png ├── README.md └── src └── DesignPattern ├── .gitattributes ├── .gitignore ├── DesignPattern ├── Behavioral │ ├── ChainOfResponsibilityPattern │ │ ├── NoSeparationExample │ │ │ ├── Exceptions │ │ │ │ └── InsufficientPaymentException.cs │ │ │ ├── Handlers │ │ │ │ ├── IHandler.cs │ │ │ │ ├── PaymentHandler.cs │ │ │ │ └── PaymentHandlers │ │ │ │ │ ├── CreditCardHandler.cs │ │ │ │ │ ├── InvoiceHandler.cs │ │ │ │ │ └── PaypalHandler.cs │ │ │ ├── Models │ │ │ │ └── Order.cs │ │ │ └── PaymentProcessors │ │ │ │ ├── CreditCardPaymentProcessor.cs │ │ │ │ ├── IPaymentProcessor.cs │ │ │ │ ├── InvoicePaymentProcessor.cs │ │ │ │ └── PaypalPaymentProcessor.cs │ │ └── SeparationExample │ │ │ ├── Exceptions │ │ │ └── InsufficientPaymentException.cs │ │ │ ├── Models │ │ │ ├── LineItem.cs │ │ │ ├── Order.cs │ │ │ └── Payment.cs │ │ │ └── PaymentReceivers │ │ │ ├── IReceiver.cs │ │ │ ├── PaymentHandler.cs │ │ │ └── PaymentHandlers │ │ │ ├── CreditCardHandler.cs │ │ │ ├── InvoiceHnadler.cs │ │ │ └── PaypalHandler.cs │ ├── CommandPattern │ │ ├── Commands │ │ │ ├── AddToCartCommand.cs │ │ │ ├── ChangeQuantityCommand.cs │ │ │ ├── CommandManager.cs │ │ │ └── ICommand.cs │ │ ├── Models │ │ │ └── Product.cs │ │ └── Repository │ │ │ ├── IProductRepository.cs │ │ │ ├── IShoppingCartRepository.cs │ │ │ ├── ProductsRepository.cs │ │ │ └── ShoppingCartRepository.cs │ ├── Mediator │ │ ├── Chatroom.cs │ │ ├── Developer.cs │ │ ├── TeamChatroom.cs │ │ └── TeamMember.cs │ ├── Observer │ │ ├── Interfaces │ │ │ ├── IObserver.cs │ │ │ └── ISubject.cs │ │ ├── Observer.cs │ │ └── Subject.cs │ ├── StatePattern │ │ ├── AbstractState │ │ │ └── IHealth.cs │ │ ├── Context │ │ │ └── Warrior.cs │ │ └── States │ │ │ ├── Normal.cs │ │ │ ├── Strong.cs │ │ │ ├── SuperStrong.cs │ │ │ └── Weak.cs │ └── TemplateMethodPattern │ │ ├── AbstractLogger.cs │ │ └── Loggers │ │ ├── DatabaseLogger.cs │ │ ├── EmailLogger.cs │ │ └── FileLogger.cs ├── Creational │ ├── FactoryMethod │ │ ├── BankA.cs │ │ ├── BankB.cs │ │ ├── BankFactory.cs │ │ ├── IBank.cs │ │ └── IBankFactory.cs │ └── Singleton │ │ ├── AppSettings.cs │ │ └── Counter.cs ├── DesignPatterns.csproj ├── Program.cs └── Structural │ ├── AdapterPattern │ ├── Employee.cs │ ├── EmployeeAdapter.cs │ ├── ITarget.cs │ └── ThirdPartyBillingSystem.cs │ ├── CompositePattern │ ├── DirectoryItem.cs │ ├── FileItem.cs │ └── FileSystemItem.cs │ ├── DecoratorPattern │ ├── Decorators │ │ ├── SMSNotifierDecorator.cs │ │ └── WhatsAppNotifierDecorator.cs │ ├── EmailNotifier.cs │ ├── INotifier.cs │ └── NotifierDecorator.cs │ ├── FacadePattern │ ├── BasketItem.cs │ ├── Inventory.cs │ ├── InventoryOrder.cs │ ├── PaymentProcessor.cs │ ├── PurchaseInvoice.cs │ ├── PurchaseOrder.cs │ ├── ShoppingBasket.cs │ └── SmsNotofications.cs │ └── ProxyPattern │ ├── ConcereteSMSService.cs │ ├── ISMSService.cs │ └── SMSServiceProxy.cs └── DesignPatterns.sln /Design-Patterns-Glossary.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Design-Patterns-Glossary.pdf -------------------------------------------------------------------------------- /Design-Patterns_Course-Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Design-Patterns_Course-Notes.pdf -------------------------------------------------------------------------------- /Images/FactoryMethodUML-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/FactoryMethodUML-ex.png -------------------------------------------------------------------------------- /Images/FactoryMethodUML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/FactoryMethodUML.png -------------------------------------------------------------------------------- /Images/MVC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/MVC.png -------------------------------------------------------------------------------- /Images/adapter-diagram-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/adapter-diagram-1.png -------------------------------------------------------------------------------- /Images/adapter-diagram-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/adapter-diagram-2.png -------------------------------------------------------------------------------- /Images/adapter-diagram-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/adapter-diagram-3.png -------------------------------------------------------------------------------- /Images/chainOfResponsibility-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/chainOfResponsibility-1.png -------------------------------------------------------------------------------- /Images/chainOfResponsibility-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/chainOfResponsibility-2.png -------------------------------------------------------------------------------- /Images/chainOfResponsibility-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/chainOfResponsibility-3.png -------------------------------------------------------------------------------- /Images/chainOfResponsibility-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/chainOfResponsibility-4.png -------------------------------------------------------------------------------- /Images/command-pattern-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/command-pattern-1.png -------------------------------------------------------------------------------- /Images/command-pattern-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/command-pattern-2.png -------------------------------------------------------------------------------- /Images/command-pattern-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/command-pattern-3.png -------------------------------------------------------------------------------- /Images/command-pattern-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/command-pattern-4.png -------------------------------------------------------------------------------- /Images/command-pattern-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/command-pattern-5.png -------------------------------------------------------------------------------- /Images/composite-diagram-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/composite-diagram-1.png -------------------------------------------------------------------------------- /Images/composite-diagram-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/composite-diagram-2.png -------------------------------------------------------------------------------- /Images/composite-diagram-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/composite-diagram-3.png -------------------------------------------------------------------------------- /Images/composite-diagram-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/composite-diagram-4.png -------------------------------------------------------------------------------- /Images/composite-diagram-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/composite-diagram-5.png -------------------------------------------------------------------------------- /Images/decorator-adding-functionality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/decorator-adding-functionality.png -------------------------------------------------------------------------------- /Images/decorator-diagram-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/decorator-diagram-1.png -------------------------------------------------------------------------------- /Images/decorator-diagram-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/decorator-diagram-2.png -------------------------------------------------------------------------------- /Images/decorator-diagram-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/decorator-diagram-3.png -------------------------------------------------------------------------------- /Images/facade-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/facade-1.png -------------------------------------------------------------------------------- /Images/facade-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/facade-2.png -------------------------------------------------------------------------------- /Images/mediator-pattern-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/mediator-pattern-1.png -------------------------------------------------------------------------------- /Images/mediator-pattern-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/mediator-pattern-2.png -------------------------------------------------------------------------------- /Images/mediator-pattern-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/mediator-pattern-3.png -------------------------------------------------------------------------------- /Images/mediator-pattern-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/mediator-pattern-4.png -------------------------------------------------------------------------------- /Images/mediator-pattern-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/mediator-pattern-5.png -------------------------------------------------------------------------------- /Images/mediator-pattern-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/mediator-pattern-6.png -------------------------------------------------------------------------------- /Images/observe-pattern-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/observe-pattern-1.png -------------------------------------------------------------------------------- /Images/observe-pattern-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/observe-pattern-2.png -------------------------------------------------------------------------------- /Images/proxy-diagram-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/proxy-diagram-1.png -------------------------------------------------------------------------------- /Images/proxy-diagram-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/proxy-diagram-2.png -------------------------------------------------------------------------------- /Images/proxy-diagram-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/proxy-diagram-3.png -------------------------------------------------------------------------------- /Images/singleton-uml.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/singleton-uml.jpg -------------------------------------------------------------------------------- /Images/state-pattern-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/state-pattern-1.png -------------------------------------------------------------------------------- /Images/state-pattern-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/state-pattern-2.png -------------------------------------------------------------------------------- /Images/state-pattern-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/state-pattern-3.png -------------------------------------------------------------------------------- /Images/template-method-pattern-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/template-method-pattern-1.png -------------------------------------------------------------------------------- /Images/template-method-pattern-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/Images/template-method-pattern-2.png -------------------------------------------------------------------------------- /OOD/Categories-of-Objects.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/Categories-of-Objects.pdf -------------------------------------------------------------------------------- /OOD/OOD-Glossary.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/OOD-Glossary.pdf -------------------------------------------------------------------------------- /OOD/Object-Oriented-Design_Course-Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/Object-Oriented-Design_Course-Notes.pdf -------------------------------------------------------------------------------- /OOD/README.md: -------------------------------------------------------------------------------- 1 | ## Table of Contents 2 | - [Software Architect and Design Roles in Industry](#software-architect-and-design-roles-in-industry) 3 | - [Object-Oriented Modeling](#object-oriented-modeling) 4 | - [**why should you use objects to represent things in your code?**](#why-should-you-use-objects-to-represent-things-in-your-code) 5 | - [Design in the Software Process](#design-in-the-software-process) 6 | - [Example](#example) 7 | - [**Satisfying Qualities**](#satisfying-qualities) 8 | - [Class Responsibility Collaborator (CRC)](#class-responsibility-collaborator-crc) 9 | - [Object-Oriented Modeling](#object-oriented-modeling-1) 10 | - [Evolution of Programming Languages](#evolution-of-programming-languages) 11 | - [Four Design Principles](#four-design-principles) 12 | - [Abstraction](#abstraction) 13 | - [Encapsulation](#encapsulation) 14 | - [Decomposition](#decomposition) 15 | - [Generalization](#generalization) 16 | - [Design Principles](#design-principles) 17 | - [Evaluating Design Complexity](#evaluating-design-complexity) 18 | - [Coupling and Cohesion](#coupling-and-cohesion) 19 | - [**Coupling**](#coupling) 20 | - [Cohesion](#cohesion) 21 | - [**Separation of Concerns**](#separation-of-concerns) 22 | - [Information Hiding](#information-hiding) 23 | - [Conceptual Integrity](#conceptual-integrity) 24 | - [Modelling Behaviour](#modelling-behaviour) 25 | - [Inheritance Issues](#inheritance-issues) 26 | - [UML Sequence Diagrams](#uml-sequence-diagrams) 27 | - [UML State Diagram](#uml-state-diagram) 28 | - [Model Checking](#model-checking) 29 | 30 | # Software Architect and Design Roles in Industry 31 | the software designer or a software architect role can look very different from company to company in Characteristics like company size, the scope of the project, the experience of the development team, the organizational structure and the age of the company 32 | 33 | Software Designer responsible for outlining a software solution to a specific problem by design the details of individual components and their responsibilities. 34 | in short: software looks at the lower-lever aspects of the system, focuses on the smaller spaces within. 35 | 36 | **Software Architect** responsible for looking the entire system and choosing appropriate frameworks, data storage, solutions and determining how components interact with each other 37 | 38 | **in short:** software looks at the higher-lever/bigger picture aspects of the system, focuses on the major structures and services. 39 | **Great software designers and architects are detail-oriented, forward thinkers** 40 | 41 | # Object-Oriented Modeling 42 | when solving a problem, object-oriented modeling involves the practice of representing key concepts through **objects** in your software. Depending on the **problem**, **many concepts,** even **instances of people, places,** or things become **distinct objects** in the software 43 | ### **why should you use objects to represent things in your code?** 44 | 45 | - to keeping your code **organized, flexible and reusable** 46 | - keeps code organized by having **related details and specific functions** in distinct, easy to find places to creates **flexibility** 47 | - flexibility enable you **easily change details** in a modular way **without affecting the rest of the code,** and **reuse code to keep your program simple.** 48 | 49 | **With object-oriented thinking,** you often think of everything as objects event living things and all these objects are self-aware event inanimate things. 50 | 51 | # Design in the Software Process 52 | 53 | you can think of developing software as a **process that takes a problem and produces a solution** involving software. 54 | 55 | it's an iterative process, taking set of requirements ⇒ working and tested implementation ⇒ building a complete solution 56 | ![](https://github.com/aboelkassem/Design-Patterns/blob/main/OOD/images/agile-process.png) 57 | Why projects fail ? it's related to issues in requirements and design 58 | 59 | so it's important to take your time in gathering/understanding the requirements and create a design 60 | 61 | ![](https://github.com/aboelkassem/Design-Patterns/blob/main/OOD/images/misunderstanding-requirments.png) 62 | We get **requirements** by asking **questions** about issues that the clients may not **considered** beside **identifying specific needs.** 63 | 64 | So to know the trade-offs the client needs to make in the solution with a **clear idea** of what you are trying to **accomplish,** you can use **Conceptual Design mock-ups** and **Technical Design diagrams.** 65 | For the design phase, you will have to think like an **architect**, which mean thinking about the structure and behavior of your software. 66 | 67 | starting with **eliciting requirements** which involves not only listening to what the client is telling you, but asking questions to clarify what the client has not told you, once this revealing follow up questions you now have an initial set of requirements allowing you to start thinking of possible designs. 68 | 69 | this requirements involves producing a Conceptual Design and Technical Design which representing two kinds of artifacts ⇒ **Conceptual mockups** and **Technical diagrams** 70 | 71 | **Conceptual mockups** provide your initial thoughts for how the requirements will be satisfied, focusing in **components** and **connections**, each component has a **responsibility** of it do or what the it's purpose and avoid technical details to clarify design decisions with clients and users. 72 | 73 | **in software conceptual mockups can be a hand drawn sketch or draw made using computer tools.** 74 | 75 | **Technical diagrams** is responsible for describing how these responsibilities are met, by start specifying the technical details of each component, this done by splitting components into smaller and smaller components to help coordinate development work. 76 | 77 | **Components** turn into collections of function, classes or other components, these pieces then represent much simpler problem that developers can implement. 78 | 79 | ### Example 80 | 81 | for university course search website task 82 | 83 | **Requirement** ⇒ As a learner, I want to search for relevant courses through a search page 84 | 85 | **Conceptual mockups** ⇒ components like search page and course, search page has the responsibility of searching for a relevant courses. 86 | 87 |

88 | 89 |

90 | 91 | **Technical design ⇒** take each component by technical details by answering the following question....how does the search page fulfill its responsibility of searching? 92 | 93 | - does the page need to talk to an external system ? or the university already has a course database component to connect Search Page Component with Course Database Component 94 |

95 | 96 |

97 | 98 | **if the design satisfying requirements ?** some software design decisions will involve tradeoffs in different quality attributes such as **performance**, **convenience** and **security.** so it's important to consider how quality attributes can compete in a proposed solution under different situations. Then, taking this into account and weighing it against the requirements of the product, a suitable compromise can be determined. 99 | 100 | ### **Satisfying Qualities** 101 | 102 | Qualities are achieved through satisfying functional and nonfunctional requirements, which in turn are the basis for the design process. 103 | 104 | For software, there are **Functional Requirements** that describe that system or application is expected to do. For example, if you are designing a media app, the app must be able to download and play a full length movie. So the key quality is simply **correctness** to build software design solution to meet such requirements correctly. 105 | 106 | **Non-Functional Requirements** that specify how well the system or application **does what it does**. Such requirements may describe how well the software runs in particular situations. Non-functional requirements to satisfy might include **performance, resource usage, and efficiency**; these requirements can be measured from the running software. For example the media app can have non-functional requirements to download a full length movie at a specific speed and to play such a movie within a memory limit. other qualities non-function satisfies is **reusability, flexibility, and maintainability.** 107 | 108 | After design get detailed and implementation is constructed, required qualities should be verified though techniques like **reviews** and **tests,** also **feedback from end-users.** 109 | 110 | You must satisfy qualities that matter to users as well as for it's developers, so when your software structure suits the balance of qualities desired, how structure is organized may affect the **performance** as seen by the **users,** as well as the **re-usability and maintainability** as seen by the **developers.** 111 | 112 | Below are some common trade-offs in qualities for software design: 113 | 114 | - Performance and maintainability – High performance code may be **less clear** and **less modular**, making it **harder to maintain.** Alternately, extra code for backward compatibility 115 | - Performance and security – Extra overhead for high security may **reduce performance** 116 | 117 | so you have to strike a **balance** during design. You should ask how much performance, maintainability, security or backward compatibility is needed. 118 | 119 | ### Class Responsibility Collaborator (CRC) 120 | 121 | when identifying **components, connections and responsibilities** from some requirements when forming the conceptual design. CRC cards hep you to **organize your components into classes**, identifying the **responsibilities** and determine how they will **collaborate with each other.** It **record and organize and refine** the components into your software. 122 | 123 | - CRC Structure 124 |

125 | 126 |

127 | **Collaborators** are other classes that the class **interacts** with to fulfill its responsibilities. So in collaborators section you list other components that your current component connects with. 128 | 129 | **Example on ATM bank machine.** 130 |

131 | 132 | 133 |

134 | 135 | **CRC** help you to organize the your ideas and extract the needed objects and it's relationships. and can be used for prototyping and simulation. 136 | 137 | **For example**, you may wondering in above example, **How bank machine authenticate bank customer ?** 138 | 139 | So this add another component is **Bank** to authenticate from it. another question **how this back and bank machine communicate ?** it add another component is **Network,** also we need to **secure this network** so we will add another component is **Encryption** and so far. 140 | 141 | Also you man notice that bank machine consist of other objects like **Card Reader, Keypad, Display, Cheque Slot, Cash Dispenser.** can be written in their own cards 142 | 143 | # Object-Oriented Modeling 144 | 145 | One approach to help make the design process easier is the object-oriented approach. This allows for the description of concepts in the problem and solution spaces as **objects**. objects are a notion that can be understood by both users and developers, because **object-oriented thinking** applies to many fields. This shared knowledge makes it possible for users and developers to discuss elements of complex problems. 146 | 147 | Even here, you don't go straight from the problem to writing the code, you have to do **Conceptual Design involving Object-Oriented Analysis** to identify the key objects in the problem. also **Technical Design involving Object-Oriented Design** to further refine the details of the objects including their attributes and behaviors. 148 | 149 | The goal during Software Design is to construct and refine **models** of all the objects, these models are useful throughout the design process. 150 | 151 | - **Entity** where initial focus during the design is placed in the problem space. 152 | - **Control** objects that receive events and actions. 153 | - **Boundary** that connect services outside your system. 154 | 155 | The Models are expressed in a visual notation, called **Unified Modelling Language (UML).** 156 | ## Evolution of Programming Languages 157 | 158 | Programming languages evolved in similar fashion as **traditional languages**, each new programming language was developed to provide **solutions** to problems that previous languages were unable to adequately address. The ideas used in computer languages have caused a shift in **programming paradigms.** 159 | 160 | In 1980s, Object-Oriented Design that are central of object-oriented programming became popular. 161 | 162 | **The goal of object-oriented design is to:** 163 | 164 | - Make an abstract data type easier write. 165 | - Structure a system around abstract data types called **classes** 166 | - Introduce the ability for an abstract data type to extend another by introducing a concept called **inheritance** 167 | 168 | The advantages of using programming paradigms like OOP is that the system will mimic the structure of the problem meaning that any object-oriented program is capable of representing **real world objects** or ideas with more fidelity that allows developers to compartmentalize the data and how it can be manipulated in their own separate classes. 169 | 170 | So **Object-Oriented Programming** is the **predominate programming paradigm.** 171 | 172 | Most modern programming languages like Java, C++, C# are founded based on objects. 173 | 174 | **Why this history ?** 175 | 176 | as a developer you need to have a broad **understanding of what is out there in the industry today,** There are many systems that still use the older languages and design paradigms. 177 | 178 | Also Object-oriented programming is a powerful tool, but is not only in your toolbox. Object-oriented design is not always the best approach for every thing because the design may not fit the problem, Remember to be efficient with your time event if this means taking a non-object-oriented approach. 179 | 180 | Here is some **history of programming languages** and paradigms and the issues they met. 181 | ![](https://github.com/aboelkassem/Design-Patterns/blob/main/OOD/images/COBOL-Fortran.png) 182 | ![](https://github.com/aboelkassem/Design-Patterns/blob/main/OOD/images/C.png) 183 | ![](https://github.com/aboelkassem/Design-Patterns/blob/main/OOD/images/Pascal.png) 184 | ![](https://github.com/aboelkassem/Design-Patterns/blob/main/OOD/images/c%2B%2B_java_c%23.png) 185 | 186 | ## Four Design Principles 187 | 188 | Object-oriented programming allows you to create models of how objects are represented in your system. However, to create an object-oriented program, you must examine the major design principles of such programs. Four of these major principles are: **abstraction, encapsulation, decomposition, and generalization.** 189 | 190 | ### Abstraction 191 | 192 | Abstraction is one of the main ways that humans deal with complexity. It is the idea of simplifying a concept in the problem domain to its essentials within some **context**. Abstraction allows you to better understand a concept by breaking it down into a simplified description that **ignores unimportant details.** Also an abstraction for a concept should **make sense** for the concept's purpose. This idea applies **the Rule Of Least Astonishment** 193 | 194 | **Rule Of Least Astonishment:** is the abstraction captures the essential attributes and behavior for a concept with **no surprises and no definitions** that fall beyond its scope. You don't want to surprise anyone trying to understand your abstraction with **irrelevant characteristics**. 195 | 196 | It's up to you to choose the abstraction that is most appropriate for your purpose depending the context of your app. 197 | 198 | **For example** the context is an academic setting, so abstraction for a student will be the essential characteristics/attributes of him: 199 | 200 | - The courses they are currently taking 201 | - Their grades in each course 202 | - The Student ID number 203 | 204 | Another examples for defining attributes of a cat from the context of a cat owner 205 | 206 | - A cat will have basic attributes like name, color, favorite Nap location, microchip number 207 | 208 | Also abstraction should describe a base **behaviors**, Like for **student** would be Studying, doing assignments, attending lectures which are responsibilities that student abstraction does for it's purpose. 209 | 210 | **Example** of abstraction of lion 211 | 212 | - attributes like age, beard, size and it's color 213 | - behaviors like hunting, eating and sleeping 214 | 215 | In abstraction anything other than a concept's essential **attributes and behaviors** is irrelevant focusing the context and purpose of this object into our app to simplifying your class design so the are more focused and understandable to someone else viewing them. 216 | 217 | **Abstraction UML Class diagram and C# Code** 218 | 219 | Thinking of how we abstract **Food** object in CRC and Class diagram 220 | 221 |

222 | 223 |

224 | 225 | Class diagram contains 226 | 227 | - Class Name which is **Food** 228 | - Properties which define C# Members ⇒ [variable name]:[variable type] 229 | - Operations which define C# Methods ⇒ name( [parameter list] ): [return type] 230 | 231 | Class diagram are very close to implementation which making the translation to code very easy 232 | 233 | So the following code is implemented of above class diagram 234 | 235 | ```csharp 236 | public class Food 237 | { 238 | public string GroceryId{ get; set; } 239 | public string Name{ get; set; } 240 | public string Manufacturer{ get; set; } 241 | public Date ExpiryDate{ get; set; } 242 | public double Price{ get; set; } 243 | 244 | public bool IsOnSale(){ 245 | 246 | } 247 | } 248 | ``` 249 | 250 | ### Encapsulation 251 | 252 | Encapsulation is a fundamental design principle in object oriented modeling and programming, Encapsulation forms a self-contained object by **bundling** the **data and functions** it requires to work, **expose an interface** whereby other objects can access and use it , **restricts access** to certain inside details. It keeps software modular, easier to work with and easy to manage. 253 | 254 | So after **Abstraction** that determine the attributes and behaviors that are relevant about concept in some context ⇒ **Encapsulation** ensures that these characteristics are bundled together in the same class 255 | 256 | - **For example** Student object should "**knows**" relevant data like degree program, Course object would "**know**" a list of students taking it, Professor object would "**know**" a list of courses teaches. 257 | 258 | Also the methods manipulate the attribute values in object to achieve the actual behaviors, by **Exposing** some methods to be accessible to objects, and **restricts** other. 259 | 260 | - **For example** Course can provide a method to allow a student to enroll in the course or Course allow professor to see the students in that course. 261 | 262 | **Encapsulation helps with data integrity** so you can define methods and attributes of class to be **restricted** from outside to access except through specific methods. 263 | 264 | **Encapsulation can secure sensitive information** for example, allowing a Student class to store a degree program and GPA without reveals it's actual value so it has a method tells whether the student is in good standing for the degree program or not. 265 | 266 | **Encapsulation helps with software changes** so the accessible interface of class will remain the same, while implementation of attributes and methods can change. 267 | 268 | - **For example** Professor need to know student GPA, student have many ways to calculate his GPA like entering Student Information system or go to administrator to get. So Professor don't care how the student will get from. 269 | 270 | In programming, this thinking called **Black Box** Thinking, you think of a class like a black box that you cannot see details inside of how attributes are represented or how methods compute the result, you just provide inputs and obtain outputs by calling methods so it doesn't matter what happens in the box to achieve the expected behaviors. 271 | 272 | **Encapsulation** achieves **Abstraction Barrier** since the internal workings are not relevant to outside world to **reduces complexity** for the users of a class and **increases reusability** because another class only need to know the right method to call to get desired behavior. 273 | 274 | **Encapsulation UML Class diagram and C# Code Example** 275 | 276 | There are two different kinds of methods typically used to preserve data integrity. These are: 277 | 278 | - **Getter Methods** are methods that retrieve data, and their names typically begin with get and end with the name of the attribute whose value you will be returning. 279 | - **Setter Methods** change data, and their name typically begin with set and end with the name of the variable you wish to set. Also Setters are used to **set private attribute** in a safe way. 280 | 281 |

282 | 283 |

284 | 285 | ```csharp 286 | public class Student 287 | { 288 | private float gpa; 289 | private string degreeProgram; 290 | 291 | public float getGPA(){ 292 | return gpa; 293 | } 294 | public void setGPA(float newGPA){ 295 | gpa = newGPA; 296 | } 297 | public string getDegreeProgram(){ 298 | return DegreeProgram; 299 | } 300 | public void setDegreeProgram(string newDegreeProgram){ 301 | if (gpa > 2.7){ 302 | degreeProgram = newDegreeProgram; 303 | } 304 | } 305 | } 306 | ``` 307 | 308 | ### Decomposition 309 | Decomposition is taking a **whole** thing and dividing it up into different **parts**, Or on flip side, taking a bunch of separate parts with different functionalities and **combining** them together to form a whole, Decomposition allows you to further beak down problems into pieces that are easier to understand and solve. 310 | 311 | **The general rule** for decomposition it to look at the different responsibilities of the some **whole** thing, and evaluate how you can **separate** them into different parts each with its own responsibility. 312 | 313 | - **For example** when identifying the different parts of a **car** like transmission, motor, wheels, tires, doors, windows, seats and fuel. each of this part had a specific purpose to achieve the responsibilities of the whole. 314 | 315 | **The Nature of Parts** 316 | 317 | A whole might have a **fixed** or **dynamic** number of a certain type of part. 318 | 319 | - If there is a **fixed number** then over the lifetime of the whole object it will have exactly that much of the part object, **for example** a refrigerator have fixed number of freezers and not change over time. 320 | - Sometimes parts with a **dynamic number** meaning the whole object may gain new instances of those part objects objects over its lifetime, **for example** a refrigerator can have a dynamic number of food items over time, or passengers in car. 321 | 322 | Note that a **part** can also serve as a **whole**, which is made up of further **parts**. For example, a kitchen is a part of a house. But the kitchen may be made up of further parts, such as an oven and a refrigerator. 323 | 324 | **Composition** involving the lifetimes of the whole object and the part objects that are be related. 325 | 326 | - **For example** the engine typically has the same lifetime as the car - when the engine goes, so does the car! The wheels, on the other hand, are replaced many times over the course of a car's life. 327 | - Whole things may also contain parts that are **shared** with another whole at the same time. However, sometimes sharing a part is not possible or intended. 328 | 329 | **Composition UML Class diagram and C# Code example** 330 | 331 | There are three types of **relationships** found in decomposition that define the interaction between the whole and the parts: 332 | 333 | - Association 334 | - Aggregation 335 | - Composition 336 | 337 | **Association** is "some" relationship. This means that there is a loose relationship/no dependent between two objects. These objects may interact with each other for some time. for example, an object of a class may use services/methods provided by object of anther class like food and wine, student and sports, kitten and yarn. each of these relationships is between completely separate entities, if one object is **destroyed**, the other can **continue to exist.** 338 | 339 | The following fig shows class diagram with two objects have association relationship 340 | 341 |

342 | 343 |

344 | 345 | 0..* ⇒ means a Person object is associated with **zero or more** airline objects and the same with Airline object is associated with **zero or more** person objects. 346 | 347 | ```csharp 348 | public class Student 349 | { 350 | public void Play(Sport sport) 351 | { 352 | // statements 353 | } 354 | } 355 | 356 | public class Sport 357 | { 358 | public string Name { get; set; } 359 | } 360 | ``` 361 | 362 | **Aggregation**: is a "Has-a" relationship where a **whole has parts** **that belong to it**, There may be sharing of parts amount the wholes this relationship. 363 | 364 | The "has-a" relationship from a whole to the parts is considered **weak "has-a"**. this means is although parts can belong to the wholes, they **can also exist independently** meaning they can **both exist without the other.** 365 | 366 | for example relationship between airliner and its crew, so without the crew an airliner would not be able to fly, However, the airliner does not cease if there is no crew on board, same for the crew they are part of airliner but the crew become destroyed if they are not on board their airliner. the entities have a relationship but can exist outside of it. like relationship between course section and student, pet stores and pets, bookshelf and books. 367 | 368 |

369 | 370 |

371 | 372 | ```csharp 373 | public class Aireliner 374 | { 375 | private List Crew; 376 | 377 | public Aireliner() 378 | { 379 | Crew = new List(); 380 | } 381 | 382 | public void AddMember(CrewMember crewMember) 383 | { 384 | Crew.Add(crewMember); 385 | // Statements 386 | } 387 | } 388 | 389 | public class CrewMember 390 | { 391 | public int Id { get; set; } 392 | public string Name { get; set; } 393 | // Statements 394 | } 395 | ``` 396 | 397 | **Composition:** is an exclusive containment of parts, otherwise known as a **strong "has-a"** relationship, this means is that the **whole cannot exist without its parts**, if it loses any of its parts the whole ceases to exist, if the whole destroyed then all of its parts are destroyed too. Usually you can only access the parts through its whole, Contained parts are exclusive to the whole, like the relationship between a house and a room, the human and brain. 398 | 399 | **Composition is the most dependent of the decomposition relationships,** it forms relationship that only exists as long as each object exists. 400 | 401 | The following diagram show class diagram of composition relationship, describes House object **has one or more** room objects. 402 | 403 |

404 | 405 |

406 | 407 | ```csharp 408 | public class Human 409 | { 410 | public Brain Brain { get; set; } 411 | public Human() 412 | { 413 | Brain = new Brain(); 414 | } 415 | } 416 | 417 | public class Brain 418 | { 419 | // statements 420 | } 421 | ``` 422 | 423 | ### Generalization 424 | 425 | Generalization helps reduce redundancy when solving problems. 426 | 427 | When model behaviors using **methods** to eliminates the need to have identical code written throughout a program. like generalize repetitious code that we would need to write by making a separate method and calling it for examples 428 | 429 |

430 | 431 | 432 |

433 | 434 | **Generalization** is used when design algorithms, which are meant to be used to perform the same action on different sets of data, we generalize the actions into its own methods and simply pass the data through arguments. 435 | 436 | **Generalization** also applied on class through **Inheritance,** so we take **repeated, common and shared characteristics** between two or more classes. 437 | 438 | **Inheritance and Methods** exemplify the generalization design principle, that following technique called **Don't Repeat Yourself (D.R.Y)** which mean write programs that are capable of performing the same tasks but with less code to be more reusable and easy to maintain. 439 | 440 | **Generalization UML Class diagram and C# Code example** 441 | 442 | following figures shows how diagram inheritance in UML diagram and example 443 | 444 |

445 | 446 | 447 |

448 | 449 | ```csharp 450 | public abstract class Animal 451 | { 452 | protected int numberOfLegs; 453 | protected int numberOfTails; 454 | protected string name; 455 | 456 | public Animal(string petName, int legs, int tails) 457 | { 458 | this.name = petName; 459 | this.numberOfLegs = legs; 460 | this.numberOfTails = tails; 461 | } 462 | 463 | public virtual void walk() { /* statements */ } // to be overrided 464 | public void run() { /* statements */ } 465 | public void eat() { /* statements */ } 466 | } 467 | 468 | public class Dog: Animal 469 | { 470 | public Dog(string name, int legs, int tails): base(name, legs, tails) 471 | { } 472 | 473 | public void playFetch() { /* statements */ } 474 | 475 | // you also can override a method in super class 476 | public override void walk() { /* statements */ } 477 | } 478 | ``` 479 | 480 | **Multi-Inheritance** 481 | 482 | Super class can have many sub classes, subclass can have only inherit from one superclass. 483 | 484 |

485 | 486 |

487 | 488 | ```csharp 489 | public class Dog: Animal 490 | { 491 | public Dog(string name, int legs, int tails): base(name, legs, tails) 492 | { } 493 | 494 | public void playFetch() { /* statements */ } 495 | } 496 | 497 | public class Cat: Animal 498 | { 499 | public Cat(string name, int legs, int tails): base(name, legs, tails) 500 | { } 501 | 502 | public void playWithYarn() { /* statements */ } 503 | } 504 | ``` 505 | 506 | **Generalization with Interfaces in C# and UML** 507 | 508 | Interface is like a contract to be fulfilled by implementing classes, used to only describe behaviors. 509 | 510 | - Interface like abstract classes which cannot be instantiated, which mean you can implement **polymorphism** meaning ****when two classes have the same description of behavior but implementation may be different 511 | - Interface can inherit from other interfaces 512 | - Interface inheritance should be abused, this mean you should not be extending interfaces if you trying to create larger interface 513 | - C# and java does not support multi-inheritance classes because this cause **Data Ambiguity** meaning when subclass inherits from two or more with have the attributes with the same name or methods signature, how do we distinguish between them? 514 | - So Class can implement as many interfaces as we want 515 | 516 |

517 | 518 | 519 |

520 | 521 | ```csharp 522 | interface IAnimal 523 | { 524 | public void move(); 525 | public void speak(); 526 | public void eat(); 527 | } 528 | 529 | class Dog :IAnimal 530 | { 531 | public void eat() { /* statements */} 532 | 533 | public void move() { /* statements */} 534 | 535 | public void speak() { Console.WriteLine("Bark!"); } 536 | } 537 | 538 | class Cat : IAnimal 539 | { 540 | public void eat(){ /* statements */} 541 | 542 | public void move(){ /* statements */} 543 | 544 | public void speak() { Console.WriteLine("Meow!"); } 545 | } 546 | ``` 547 | 548 | - Classes can implement on or more interface at time, which allows them to have multiple types. 549 | - Interfaces enable you to describe behaviors without the need to implement them, which allows you to reuse these abstractions. 550 | 551 |

552 | 553 |

554 | 555 | ## Design Principles 556 | 557 | ### Evaluating Design Complexity 558 | 559 | It is important to keep modules simple when you are programming, If your design complexity which exceeds what developers can mentally handle, then bugs will occur more often. 560 | 561 | To help control this we use **Module** 562 | 563 | - Design complexity applies on both classes and methods so we use term called **Module** to refer to program unit containing classes and methods within them. 564 | - **Coupling** focuses on complexity between a module and other modules. 565 | - **Cohesion** focuses on complexity within a module. 566 | 567 | ## Coupling and Cohesion 568 | 569 | this two concepts help to better apply of OOD principles and achieve more manageable system, A system is a combination of various modules. If the system has a **bad design,** then modules can **only** connect to other **specific** modules and **nothing else.** A **good design** allows **any** modules to connect together **without much trouble**. In other words, in a good design, modules are **compatible** with one another and can therefore be easily **connected and re-used** 570 | 571 | ### **Coupling** 572 | 573 | **Coupling** for a module captures the complexity of connecting the module to other modules 574 | 575 | - If your module **is highly reliant** on other modules, say this module is **tightly coupled** to others 576 | - If your module finds **easy to connect** to other modules, say this module is **loosely coupled** to others, So it's important for you module to be **loose** or low not tight. 577 | 578 | When evaluating the Coupling of module you need to consider metrics **degree**, **ease**, and **flexibility** 579 | 580 | - **Degree** is the number of **connections** between the module and others. With coupling, you want to keep the degree **small**, For instance if the module needed to connect to other modules through a **few parameters or narrow interfaces,** then the degree would be small and coupling would be loose. 581 | - **Ease** is **how obvious** are the connections between the module and others. With coupling, you want the connections to **be easy to make** without needing to understand the implementations of the other modules. 582 | - **Flexibility** is how interchangeable the other modules are for this module. With coupling, you want the other modules **easily replaceable** **for something better** in the future. 583 | 584 | ### Cohesion 585 | 586 | Cohesion represents the clarity of the responsibilities of a module. 587 | 588 | - If your module performs **one task and nothing else** or has a clear purpose, you module has **high cohesion** 589 | - If you module tries to encapsulate **more than one purpose** or has an unclear purpose, you module has **low cohesion**. 590 | 591 | A bad design has low cohesion, if a module has more than one responsibility, it is a good idea to **split** the module. 592 | 593 | **For example** suppose you have class called **Sensor** that has **two purposes,** getting humidity and get temperature 594 | 595 | ```csharp 596 | class Sensore 597 | { 598 | public float Humidity { get; set; } 599 | public float Temperature { get; set; } 600 | 601 | public float get(int controlFlag) 602 | { 603 | switch (controlFlag) 604 | { 605 | case 0: 606 | return this.Humidity; 607 | break; 608 | case 1: 609 | return this.Temperature; 610 | break; 611 | default: 612 | throw new Exception("Unknown Control Flag"); 613 | } 614 | } 615 | } 616 | ``` 617 | 618 | Since the sensor class doesn't have a clear single purpose so it have **Low Cohesion** 619 | 620 | Since it's unclear what controlFlag means until to read inside the method itself in order to know what values to give it which lacks ease to make the get method harder to use which call **Tightly Coupled** 621 | 622 | To make it **loosely coupled and high cohesion** follow new design which split it to two classes each one has one purpose, and not hiding any information we don't need to break encapsulation to look inside the method 623 | 624 |

625 | 626 |

627 | 628 | It is important to balance between **low coupling and high cohesion** in system design. Both are necessary for a good design. 629 | 630 | For complex system can be distributed between the modules or within the modules 631 | 632 | - As modules are simplified to achieve **high cohesion**, they may need to depend more on other modules thus **increase coupling.** 633 | - As connections between modules are simplified to achieve **low coupling**, they may to need to take more responsibilities thus **lowering cohesion** 634 | 635 | ### **Separation of Concerns** 636 | 637 | Is an ongoing process throughout the design process. 638 | 639 | **Concern** is a very general notion, basically it is anything that matters in providing a solution to a problem, Which is a key idea that applies throughout object oriented modelling and programming. 640 | 641 | Consider a software system that solves a problem. That problem could either be simple, with a small number of subproblems, or complex, with a large number of subproblems. Concepts can be abstracted from the problem space. When these abstractions are implemented in the software, it can lead to more concerns 642 | 643 | How these abstractions are implemented in the software can lead to more concerns? Some of these concerns may involve: 644 | 645 | - What information the implementation represents 646 | - What it manipulates 647 | - What gets presented at the end 648 | 649 | Importance of separation of concerns: 650 | 651 | - They allow you to develop and update sections of the software independently. 652 | - Using separation of concerns also means that you do not need to know how all sections of code work in order to update a section. 653 | - It allows changes to be made to one component without requiring a change in another. 654 | 655 | The concerns that matter are addressed separately when applying the design principles of **abstraction, encapsulation, decomposition, and generalization** 656 | 657 | ⇒ each concept in the problem space leads to separate **abstraction** with its own relevant attributes and behaviors, these attribute and behaviors are **encapsulated** into their own section of code called class, The view of a class by the rest of the system and its implementation are separated, so that the details of implementation can change while the view through an interface can stay the same, A whole class can also be **decomposed** into multiple classes, we may recognize commonalities among classes which are then separated and **generalized** into a super class. 658 | 659 | **For example The Smartphone** which focus on two functionality of using camera and make calls 660 | 661 | ```csharp 662 | public class SmartPhone 663 | { 664 | private byte camera; 665 | private byte phone; 666 | 667 | public SmartPhone() { … } 668 | 669 | public void takePhoto() { … } 670 | public void savePhoto() { … } 671 | public void cameraFlash() { … } 672 | 673 | public void makePhoneCall() { … } 674 | public void encryptOutgoingSound() { … } 675 | public void decipherIncomingSound() { … } 676 | } 677 | ``` 678 | 679 | This code is **low cohesion** in SmartPhone class, because we have behaviors that are not related to each other, the camera behaviors don't need to be encapsulated with the behaviors of the phone for the camera to do its job, In addition don't offer any **modularity**, We cannot access the camera or the phone separately if we were to build another system that required only one, and we cannot replace our current camera with a different camera/different object. 680 | 681 | So to make this class more cohesive and give each component distinctive functionalities! 682 | 683 | Just check what our class is concerned about and separate them out, for example SmartPhone has two concerns 684 | 685 | - Act as a tradition phone 686 | - Be able to use the built-in camera to take pictures 687 | 688 | So after applied separation of concerns 689 | 690 |

691 | 692 |

693 | 694 | ```csharp 695 | public interface ICamera 696 | { 697 | public void takePhoto(); 698 | public void savePhoto(); 699 | public void cameraFlash(); 700 | } 701 | 702 | public interface IPhone 703 | { 704 | public void makePhoneCall(); 705 | public void encryptOutgoingSound(); 706 | public void deciphereIncomingSound(); 707 | } 708 | public class FirstGenCamera: ICamera 709 | { 710 | /* Abstracted camera attributes */ 711 | } 712 | public class TraditionalPhone : IPhone 713 | { 714 | /* Abstracted phone attributes */ 715 | } 716 | 717 | public class SmartPhone 718 | { 719 | private ICamera myCamera; 720 | private IPhone myPhone; 721 | 722 | public SmartPhone(ICamera aCamera, IPhone aPhone) 723 | { 724 | this.myCamera = aCamera; 725 | this.myPhone = aPhone; 726 | } 727 | 728 | public void useCamera() 729 | { 730 | this.myCamera.takePhoto(); 731 | } 732 | public void usePhone() 733 | { 734 | this.myPhone.makePhoneCall(); 735 | } 736 | } 737 | ``` 738 | 739 | So now if we want change or swap out the camera or phone classes for something else, we don't need to touch any of the SmartPhone class's code, we just change the code to it's parts. 740 | 741 | We used separation of concerns throughout this example by separating out the general notions of camera and phone through applying **generalization** and defining two interfaces, separating out the functionality for a FirstGenCamera and TraditionalPhone by applying **abstraction** and **encapsulation**, finally by applying **decomposition** to the smartphone so the parts are separated from the whole. by applying this the code will be organized so that it only contains the code that needs it do its job 742 | 743 | ## Information Hiding 744 | 745 | One important thing is How to address information access? You don't need everything in your system to know about everything else. The Module should only have access to the information that it needs to do its job, we do this by applying **information hiding** 746 | 747 | Information hiding allows modules of our system to give others the minimum amount of information needed to use them correctly and "hide" everything else. which enable developer working on a module separately without other developers needing to know the implementation details. They can use it through interface. 748 | 749 | In general things that might change like **implementation details,** should be **hidden**. And things that should not change like **assumptions** are revealed through **interfaces.** 750 | 751 | **Information Hiding Through Encapsulation:** we use encapsulation to bundle attributes and behaviors into their appropriate class, and expose an interface to provide access. which allows: 752 | 753 | - Hide implementation of behaviors and only access through an interface of specific methods, So other classes rely on the information in these method signatures not the implementation 754 | - Change the implementation without changing the expected outcome 755 | 756 | So you can hide information through the use of **Access Modifiers** which C# have 4 different levels of access **Public**, **Protected**, **Private**, and **Internal** 757 | 758 | - **Attributes** with a **public** access modifier are accessible by **any class** in your system which mean other classes can retrieve and modify the attribute. **Public Methods** are also accessible by any class in your system, but does not allow other classes to **change the implementation** of the behavior for the method, just other classes call the method and receive any output. 759 | - **Protected** Methods and Attributes are not accessible to every class in the system, the are only available to the encapsulating **class itself, all subclasses, and within the same package/namespace** 760 | - **Internal** Modifier The code is only accessible within its own assembly, but not from another assembly 761 | - **Private** Attributes and methods are **not accessible** by any class other than by the **encapsulating class itself,** This mean these attributes cannot be accessed directly and these methods cannot be invoked by another classes. 762 | 763 | ### Conceptual Integrity 764 | 765 | It about creating consistent software, making decision about how your system will be designed and implemented, so if you see multiple people working on software it would seem as only on mind guiding all the work. 766 | 767 | **Conceptual integrity** does not mean that the developers in your team don't get to voice their opinions about the software, It's more about **everyone agreeing** to use certain design principles and conventions. 768 | 769 | You can achieve Conceptual integrity through: 770 | 771 | - **Communication** through adopting agile development practices like **Daily Stand-Up Meetings** and **sprint retrospectives** where team members agree to use certain libraries or methods when addressing certain issues, For example team members can all follow a particular **naming convention** 772 | - **Code Reviews** which are systematic examinations of written code like peer review in writing, which used to **find mistakes** in the software and keep different developers consistent with each other, Developers go through code line by line and uncover issues in each other’s code. 773 | - Using **Design Principles** and **Design Patterns** 774 | - Having a **well-defined design or architecture** underlying the software, While software design is associated with guiding internal design of process running as a single process, Software Architectures describe how software running as multiple processes work together which creates organized software consistency. 775 | - **Unifying concepts** is taking different concepts and finding a commonality, For example in the Unix OS every resource can be seen and manipulated as file, the same set of operations can be used on different types of resources. 776 | - Having a **small group** that accepts commits to the code base, which similar to code reviews but restricts the reviews to only members of your software team to ensure the software changes follow the overall architecture and design of the software to solve any design issues and lead to consistency. 777 | 778 | ## Modelling Behaviour 779 | 780 | ### Inheritance Issues 781 | 782 | Inheritance is a powerful design tool that can help you create clean, reusable and maintainable software systems. But **misusing** inheritance can lead to **poor code** and that happen when creating **more problems** than they are meant to solve. 783 | 784 | To know that you: 785 | 786 | - Ask yourself: "Am I using inheritance to simply share attributes or behaviors without further adding anything **special in my subclasses**?" 787 | - If the **Liskov Substitution Principle** are broken, which this principle states that a subclass can replace a superclass, if and only if the subclass does not change the functionality of superclass. 788 | 789 | Example for bad inheritance in java, In Stack data structure, the Java Stack class inherits from a Vector superclass. This means that the Stack class is able to return an element at a specified index, retrieve the index of an element, and even insert an element into a specific index. These are not behaviors normally expected from a stack. 790 | 791 | **If inheritance does not suit your need**, Just using **decomposition** will be more appropriate. 792 | 793 | For SmartPhone Example 794 | 795 |

796 | 797 |

798 | 799 | which are not make sense for SmartPhone to inherit from the phone and then add camera methods to it. So in this case we should use decomposition to extract out the camera responsibilities and put it into their own class like this: 800 | 801 |

802 | 803 |

804 | 805 | Inheritance could be a difficult design principle to apply, but still a very powerful technique. 806 | 807 | ### UML Sequence Diagrams 808 | 809 | Sequence diagram are used to show your team how **objects** in your program **interact** with each other to complete tasks. Thing it as mapping of conversation from two people/objects, it used as a planning tool before the dev team start coding to help determining the functions you will need. 810 | 811 | **For example** a person wants to order a burger at local fast food restaurant, 812 | 813 |

814 | 815 |

816 | 817 | **Components of Sequence Diagram** 818 | 819 | - **Boxes** are used to represent a role played by an object. The **role** is typically named after the class for the object 820 | - **Vertical dotted lines** known as **lifelines** to represent an object as time passes by. 821 | - **Solid line Arrows** to show **messages** that are sent from one object to another. A short description of the message is usually included above the arrow 822 | - **Dotted line arrows** are used to show a return of data and control back to initiating objects. 823 | - **Small rectangles** along an object’s lifeline denote a **method activation**. You activate an object whenever an object sends, receives, or is waiting for a message. 824 | 825 | Sequence diagrams are typically framed within a large box which show that this is **one** sequence of activities, Also Sequence diagram can contain **other sequence diagrams** within it 826 | 827 | **For example** in changing the channel of TV by using remote control. 828 | 829 |

830 | 831 |

832 | 833 | When sequence diagrams get more complicated, you can also show **Loops** and **Alternative** processes in sequence diagram, for above example when Viewer is unsure what channel to go to. and would like to surf the channels until find a channel they like 834 | 835 |

836 | 837 |

838 | 839 | ### UML State Diagram 840 | 841 | **A State Diagram** is a technique that you can use to describe how your system behaves and responds. When an event occurs you note how a system acts or behaves and show changes between states to determine the different events that might occur during object's lifetime like user inputs, and how this object behave when this event occurs like checking conditions and performing actions. 842 | 843 | **State diagrams** can describe a single object and illustrate how that object behaves in response to a series of events in your system by imaging the changing states of object. Also help finding an issues in your system like discovering a condition that didn't play for or help to create tests. 844 | 845 | **State** is the way an object exists at particular point in time, The state of an object is determined by the values of its attributes. 846 | 847 | **For example** Car with automatic transmission can have different states like park, reverse, neutral, and drive. When a car is in reverse it can only behave move backwards, if you want it to move a forwards direction you have to change the state of car. 848 | 849 | UML State Diagram components 850 | 851 | - **Filled circle** to indicate the **start state** of diagram. 852 | - **Arrows** are used to represent **events** to **transition** from one state to another 853 | - **Rounded rectangles** indicate other states which have three sections a **state name**, **state variables**, and **activities** 854 | - **State name** is the name of the state, it should be meaningful for the states of your object 855 | - **State Variables** are data relevant to the state of the object 856 | - **Activities** are actions that are performed in the state, There are three types for each state, **entry, exit and do** 857 | - **Entry** activities are actions that occur when the state is **just entered** from another state 858 | - **Exit** activities are actions that occur when the state **is exited** and moves on to another. 859 | - **Do** activities are actions that occur **once, or multiple times** 860 | - **Termination** represents an object being **destroyed** or the process being **completed** 861 | 862 | **Example** of Vending machine 863 | 864 |

865 | 866 |

867 | 868 | ### Model Checking 869 | 870 | After using many techniques to design your system, **How do you make sure that the system you've created is correct**? you can run **tests** and see if the actual behavior matches what you expect, another technique is **model checking** 871 | 872 | **Model checking** is a systematic **check** of your system's state model, you **check all the states** of your software and find that there are any **errors** by simulating different events that change the states and variables of your software. And notifies you of any violations of the rules. 873 | 874 | Model checks are performed by **model checking software**. There are different types of software available for such **tests**, some of which are free and available for developers using different languages. Model checking is typically performed during **testing** of the software 875 | 876 | Think of model checking like going through airport security, Security guards in airports know the rules of what people should have or shouldn't have to get on an airplane. 877 | 878 | Imagine software that has a rule not to produce a **deadlock, Deadlock** is a situation where your system **cannot continue** because **two tasks are waiting for the same resource.** So your **model checker** would simulate the different states that could occur in your system and if **deadlock** is possible, it would provide you details of the violation. 879 | 880 | **How do you model check your software** ? Model checkers generate a **State Model** from your code, A state model is an abstract state machine that can be in one of various states, the model checker then checks the state of model conforms to behavioral properties. For example, the model checker can examine the state model for flaws like **race conditions**, exploring all the possible states of your model. 881 | 882 | The three different phases to performing model checking : 883 | 884 | - **The Modeling phase**: where you enter **model description** in whatever programming language your system uses, describe the desired properties. 885 | - **The Running phase:** this is when you **run the model checker** to see how your model confirms to the desired properties that you've wrote in the modeling phase. 886 | - **The Analysis phase**: this is when you **check** if all the desired properties are satisfied and if any are violated (Counterexamples), proving information to you where to fix any problems. 887 | 888 | Model checking helps ensure not only that software is well designed, but also that software meets desired properties and behavior, and it works as intended. There are also many ways to test your system's behaviors like **unit testing**, beta testing and simulations 889 | -------------------------------------------------------------------------------- /OOD/User-Stories.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/User-Stories.pdf -------------------------------------------------------------------------------- /OOD/images/C.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/C.png -------------------------------------------------------------------------------- /OOD/images/COBOL-Fortran.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/COBOL-Fortran.png -------------------------------------------------------------------------------- /OOD/images/Pascal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/Pascal.png -------------------------------------------------------------------------------- /OOD/images/UMLSequence-ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/UMLSequence-ex1.png -------------------------------------------------------------------------------- /OOD/images/UMLSequence-ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/UMLSequence-ex2.png -------------------------------------------------------------------------------- /OOD/images/UMLSequence-ex3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/UMLSequence-ex3.png -------------------------------------------------------------------------------- /OOD/images/UMLState-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/UMLState-ex.png -------------------------------------------------------------------------------- /OOD/images/abstraction-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/abstraction-ex.png -------------------------------------------------------------------------------- /OOD/images/aggreg-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/aggreg-ex.png -------------------------------------------------------------------------------- /OOD/images/agile-process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/agile-process.png -------------------------------------------------------------------------------- /OOD/images/association-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/association-ex.png -------------------------------------------------------------------------------- /OOD/images/c++_java_c#.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/c++_java_c#.png -------------------------------------------------------------------------------- /OOD/images/class-vs-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/class-vs-interface.png -------------------------------------------------------------------------------- /OOD/images/composition-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/composition-ex.png -------------------------------------------------------------------------------- /OOD/images/couped-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/couped-ex.png -------------------------------------------------------------------------------- /OOD/images/crc_bank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/crc_bank.png -------------------------------------------------------------------------------- /OOD/images/crc_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/crc_card.png -------------------------------------------------------------------------------- /OOD/images/crc_customer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/crc_customer.png -------------------------------------------------------------------------------- /OOD/images/encap-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/encap-ex.png -------------------------------------------------------------------------------- /OOD/images/example1-CM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/example1-CM.png -------------------------------------------------------------------------------- /OOD/images/example1-TD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/example1-TD.png -------------------------------------------------------------------------------- /OOD/images/generalization-ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/generalization-ex1.png -------------------------------------------------------------------------------- /OOD/images/generalization-ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/generalization-ex2.png -------------------------------------------------------------------------------- /OOD/images/generlize-exp-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/generlize-exp-1.png -------------------------------------------------------------------------------- /OOD/images/generlize-exp-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/generlize-exp-2.png -------------------------------------------------------------------------------- /OOD/images/interface-ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/interface-ex1.png -------------------------------------------------------------------------------- /OOD/images/interface-ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/interface-ex2.png -------------------------------------------------------------------------------- /OOD/images/misunderstanding-requirments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/misunderstanding-requirments.png -------------------------------------------------------------------------------- /OOD/images/multi-inher-ex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/multi-inher-ex.png -------------------------------------------------------------------------------- /OOD/images/seperation-of-concerns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/seperation-of-concerns.png -------------------------------------------------------------------------------- /OOD/images/smartphone-ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/smartphone-ex1.png -------------------------------------------------------------------------------- /OOD/images/smartphone-ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkassm/Design-Patterns/066f3b3694bda62c178159885633cdb37d9acc6c/OOD/images/smartphone-ex2.png -------------------------------------------------------------------------------- /src/DesignPattern/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/DesignPattern/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # My-Custom-Ignoring-Files 7 | Listify.Backend/Domain/Listify.Paths/Globals.cs 8 | Listify.Backend/Clients/Listify.Identity/identityserver4_log.txt 9 | Listify.Backend/.vs/Listify.Backend/v16/.suo 10 | Listify/src/app/services/globals.service.ts 11 | 12 | # User-specific files 13 | *.rsuser 14 | *.suo 15 | *.user 16 | *.userosscache 17 | *.sln.docstates 18 | 19 | # User-specific files (MonoDevelop/Xamarin Studio) 20 | *.userprefs 21 | 22 | # Build results 23 | [Dd]ebug/ 24 | [Dd]ebugPublic/ 25 | [Rr]elease/ 26 | [Rr]eleases/ 27 | x64/ 28 | x86/ 29 | [Aa][Rr][Mm]/ 30 | [Aa][Rr][Mm]64/ 31 | bld/ 32 | [Bb]in/ 33 | [Oo]bj/ 34 | [Ll]og/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUNIT 49 | *.VisualState.xml 50 | TestResult.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # StyleCop 66 | StyleCopReport.xml 67 | 68 | # Files built by Visual Studio 69 | *_i.c 70 | *_p.c 71 | *_h.h 72 | *.ilk 73 | *.meta 74 | *.obj 75 | *.iobj 76 | *.pch 77 | *.pdb 78 | *.ipdb 79 | *.pgc 80 | *.pgd 81 | *.rsp 82 | *.sbr 83 | *.tlb 84 | *.tli 85 | *.tlh 86 | *.tmp 87 | *.tmp_proj 88 | *_wpftmp.csproj 89 | *.log 90 | *.vspscc 91 | *.vssscc 92 | .builds 93 | *.pidb 94 | *.svclog 95 | *.scc 96 | 97 | # Chutzpah Test files 98 | _Chutzpah* 99 | 100 | # Visual C++ cache files 101 | ipch/ 102 | *.aps 103 | *.ncb 104 | *.opendb 105 | *.opensdf 106 | *.sdf 107 | *.cachefile 108 | *.VC.db 109 | *.VC.VC.opendb 110 | 111 | # Visual Studio profiler 112 | *.psess 113 | *.vsp 114 | *.vspx 115 | *.sap 116 | 117 | # Visual Studio Trace Files 118 | *.e2e 119 | 120 | # TFS 2012 Local Workspace 121 | $tf/ 122 | 123 | # Guidance Automation Toolkit 124 | *.gpState 125 | 126 | # ReSharper is a .NET coding add-in 127 | _ReSharper*/ 128 | *.[Rr]e[Ss]harper 129 | *.DotSettings.user 130 | 131 | # JustCode is a .NET coding add-in 132 | .JustCode 133 | 134 | # TeamCity is a build add-in 135 | _TeamCity* 136 | 137 | # DotCover is a Code Coverage Tool 138 | *.dotCover 139 | 140 | # AxoCover is a Code Coverage Tool 141 | .axoCover/* 142 | !.axoCover/settings.json 143 | 144 | # Visual Studio code coverage results 145 | *.coverage 146 | *.coveragexml 147 | 148 | # NCrunch 149 | _NCrunch_* 150 | .*crunch*.local.xml 151 | nCrunchTemp_* 152 | 153 | # MightyMoose 154 | *.mm.* 155 | AutoTest.Net/ 156 | 157 | # Web workbench (sass) 158 | .sass-cache/ 159 | 160 | # Installshield output folder 161 | [Ee]xpress/ 162 | 163 | # DocProject is a documentation generator add-in 164 | DocProject/buildhelp/ 165 | DocProject/Help/*.HxT 166 | DocProject/Help/*.HxC 167 | DocProject/Help/*.hhc 168 | DocProject/Help/*.hhk 169 | DocProject/Help/*.hhp 170 | DocProject/Help/Html2 171 | DocProject/Help/html 172 | 173 | # Click-Once directory 174 | publish/ 175 | 176 | # Publish Web Output 177 | *.[Pp]ublish.xml 178 | *.azurePubxml 179 | # Note: Comment the next line if you want to checkin your web deploy settings, 180 | # but database connection strings (with potential passwords) will be unencrypted 181 | *.pubxml 182 | *.publishproj 183 | 184 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 185 | # checkin your Azure Web App publish settings, but sensitive information contained 186 | # in these scripts will be unencrypted 187 | PublishScripts/ 188 | 189 | # NuGet Packages 190 | *.nupkg 191 | # The packages folder can be ignored because of Package Restore 192 | **/[Pp]ackages/* 193 | # except build/, which is used as an MSBuild target. 194 | !**/[Pp]ackages/build/ 195 | # Uncomment if necessary however generally it will be regenerated when needed 196 | #!**/[Pp]ackages/repositories.config 197 | # NuGet v3's project.json files produces more ignorable files 198 | *.nuget.props 199 | *.nuget.targets 200 | 201 | # Microsoft Azure Build Output 202 | csx/ 203 | *.build.csdef 204 | 205 | # Microsoft Azure Emulator 206 | ecf/ 207 | rcf/ 208 | 209 | # Windows Store app package directories and files 210 | AppPackages/ 211 | BundleArtifacts/ 212 | Package.StoreAssociation.xml 213 | _pkginfo.txt 214 | *.appx 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- Backup*.rdl 265 | 266 | # Microsoft Fakes 267 | FakesAssemblies/ 268 | 269 | # GhostDoc plugin setting file 270 | *.GhostDoc.xml 271 | 272 | # Node.js Tools for Visual Studio 273 | .ntvs_analysis.dat 274 | node_modules/ 275 | 276 | # Visual Studio 6 build log 277 | *.plg 278 | 279 | # Visual Studio 6 workspace options file 280 | *.opt 281 | 282 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 283 | *.vbw 284 | 285 | # Visual Studio LightSwitch build output 286 | **/*.HTMLClient/GeneratedArtifacts 287 | **/*.DesktopClient/GeneratedArtifacts 288 | **/*.DesktopClient/ModelManifest.xml 289 | **/*.Server/GeneratedArtifacts 290 | **/*.Server/ModelManifest.xml 291 | _Pvt_Extensions 292 | 293 | # Paket dependency manager 294 | .paket/paket.exe 295 | paket-files/ 296 | 297 | # FAKE - F# Make 298 | .fake/ 299 | 300 | # JetBrains Rider 301 | .idea/ 302 | *.sln.iml 303 | 304 | # CodeRush personal settings 305 | .cr/personal 306 | 307 | # Python Tools for Visual Studio (PTVS) 308 | __pycache__/ 309 | *.pyc 310 | 311 | # Cake - Uncomment if you are using it 312 | # tools/** 313 | # !tools/packages.config 314 | 315 | # Tabs Studio 316 | *.tss 317 | 318 | # Telerik's JustMock configuration file 319 | *.jmconfig 320 | 321 | # BizTalk build output 322 | *.btp.cs 323 | *.btm.cs 324 | *.odx.cs 325 | *.xsd.cs 326 | 327 | # OpenCover UI analysis results 328 | OpenCover/ 329 | 330 | # Azure Stream Analytics local run output 331 | ASALocalRun/ 332 | 333 | # MSBuild Binary and Structured Log 334 | *.binlog 335 | 336 | # NVidia Nsight GPU debugger configuration file 337 | *.nvuser 338 | 339 | # MFractors (Xamarin productivity tool) working folder 340 | .mfractor/ 341 | 342 | # Local History for Visual Studio 343 | .localhistory/ 344 | 345 | # BeatPulse healthcheck temp database 346 | healthchecksdb 347 | Listify.Backend/.vs/Listify.Backend/v16/.suo 348 | Listify.Backend/Clients/Listify.Identity/identityserver4_log.txt 349 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/Exceptions/InsufficientPaymentException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Exceptions 6 | { 7 | public class InsufficientPaymentException : Exception 8 | { 9 | public InsufficientPaymentException() : base() 10 | { 11 | } 12 | 13 | public InsufficientPaymentException(string message) : base(message) 14 | { 15 | } 16 | 17 | public InsufficientPaymentException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | public override string Message 22 | { 23 | get 24 | { 25 | return "Sorry, this payment doesn't have sufficient money for complete the order"; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/Handlers/IHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Handlers 6 | { 7 | public interface IHandler where T : class 8 | { 9 | IHandler SetNext(IHandler next); 10 | void Handle(T request); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/Handlers/PaymentHandler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Exceptions; 2 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Handlers 8 | { 9 | public abstract class PaymentHandler : IHandler 10 | { 11 | private IHandler Next { get; set; } 12 | 13 | public virtual void Handle(Order order) 14 | { 15 | Console.WriteLine($"Running: {GetType().Name}"); 16 | 17 | if (Next == null && order.AmountDue > 0) 18 | { 19 | throw new InsufficientPaymentException(); 20 | } 21 | 22 | if (order.AmountDue > 0) 23 | { 24 | Next.Handle(order); 25 | } 26 | else 27 | { 28 | order.ShippingStatus = ShippingStatus.ReadyForShippment; 29 | } 30 | } 31 | 32 | public IHandler SetNext(IHandler next) 33 | { 34 | Next = next; 35 | 36 | return Next; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/Handlers/PaymentHandlers/CreditCardHandler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 2 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.PaymentProcessors; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Handlers.PaymentHandlers 9 | { 10 | public class CreditCardHandler : PaymentHandler 11 | { 12 | public CreditCardPaymentProcessor CreditCardPaymentProcessor { get; } 13 | = new CreditCardPaymentProcessor(); 14 | 15 | public override void Handle(Order order) 16 | { 17 | if (order.SelectedPayments.Any(x => x.PaymentProvider == PaymentProvider.CreditCard)) 18 | { 19 | CreditCardPaymentProcessor.Finalize(order); 20 | } 21 | 22 | base.Handle(order); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/Handlers/PaymentHandlers/InvoiceHandler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 2 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.PaymentProcessors; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Handlers.PaymentHandlers 9 | { 10 | public class InvoiceHandler : PaymentHandler 11 | { 12 | public InvoicePaymentProcessor InvoicePaymentProcessor { get; } 13 | = new InvoicePaymentProcessor(); 14 | 15 | public override void Handle(Order order) 16 | { 17 | if (order.SelectedPayments.Any(x => x.PaymentProvider == PaymentProvider.Invoice)) 18 | { 19 | InvoicePaymentProcessor.Finalize(order); 20 | } 21 | base.Handle(order); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/Handlers/PaymentHandlers/PaypalHandler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 2 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.PaymentProcessors; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Handlers.PaymentHandlers 9 | { 10 | public class PaypalHandler : PaymentHandler 11 | { 12 | private PaypalPaymentProcessor PaypalPaymentProcessor { get; } 13 | = new PaypalPaymentProcessor(); 14 | 15 | public override void Handle(Order order) 16 | { 17 | if (order.SelectedPayments.Any(x => x.PaymentProvider == PaymentProvider.Paypal)) 18 | { 19 | PaypalPaymentProcessor.Finalize(order); 20 | } 21 | 22 | base.Handle(order); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/Models/Order.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models 7 | { 8 | public class Order 9 | { 10 | public Dictionary LineItems { get; } = new Dictionary(); 11 | 12 | public IList SelectedPayments { get; } = new List(); 13 | 14 | public IList FinalizedPayments { get; } = new List(); 15 | 16 | public decimal AmountDue => LineItems.Sum(item => item.Key.Price * item.Value) - FinalizedPayments.Sum(payment => payment.Amount); 17 | 18 | public ShippingStatus ShippingStatus { get; set; } = ShippingStatus.WaitingForPayment; 19 | } 20 | 21 | public enum ShippingStatus 22 | { 23 | WaitingForPayment, 24 | ReadyForShippment, 25 | Shipped 26 | } 27 | 28 | public enum PaymentProvider 29 | { 30 | Paypal, 31 | CreditCard, 32 | Invoice 33 | } 34 | 35 | public class Payment 36 | { 37 | public decimal Amount { get; set; } 38 | public PaymentProvider PaymentProvider { get; set; } 39 | } 40 | 41 | public class Item 42 | { 43 | public string Id { get; } 44 | public string Name { get; } 45 | public decimal Price { get; } 46 | 47 | public Item(string id, string name, decimal price) 48 | { 49 | Id = id; 50 | Name = name; 51 | Price = price; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/PaymentProcessors/CreditCardPaymentProcessor.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.PaymentProcessors 8 | { 9 | public class CreditCardPaymentProcessor : IPaymentProcessor 10 | { 11 | public void Finalize(Order order) 12 | { 13 | // Invoke the Stripe API 14 | var payment = order.SelectedPayments 15 | .FirstOrDefault(x => x.PaymentProvider == PaymentProvider.CreditCard); 16 | 17 | if (payment == null) return; 18 | 19 | order.FinalizedPayments.Add(payment); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/PaymentProcessors/IPaymentProcessor.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.PaymentProcessors 7 | { 8 | public interface IPaymentProcessor 9 | { 10 | void Finalize(Order order); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/PaymentProcessors/InvoicePaymentProcessor.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.PaymentProcessors 8 | { 9 | public class InvoicePaymentProcessor : IPaymentProcessor 10 | { 11 | public void Finalize(Order order) 12 | { 13 | // Create an invoice and email it 14 | 15 | var payment = order.SelectedPayments 16 | .FirstOrDefault(x => x.PaymentProvider == PaymentProvider.Invoice); 17 | 18 | if (payment == null) return; 19 | 20 | order.FinalizedPayments.Add(payment); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/NoSeparationExample/PaymentProcessors/PaypalPaymentProcessor.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.NoSeparationExample.PaymentProcessors 8 | { 9 | public class PaypalPaymentProcessor : IPaymentProcessor 10 | { 11 | public void Finalize(Order order) 12 | { 13 | // Invoke the Paypal API to finalize payment 14 | 15 | var payment = order.SelectedPayments 16 | .FirstOrDefault(x => x.PaymentProvider == PaymentProvider.Paypal); 17 | 18 | if (payment == null) return; 19 | 20 | order.FinalizedPayments.Add(payment); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/Exceptions/InsufficientPaymentException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Exceptions 6 | { 7 | public class InsufficientPaymentException : Exception 8 | { 9 | public InsufficientPaymentException() : base() 10 | { 11 | } 12 | 13 | public InsufficientPaymentException(string message) : base(message) 14 | { 15 | } 16 | 17 | public InsufficientPaymentException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | public override string Message 22 | { 23 | get 24 | { 25 | return "Sorry, this payment doesn't have sufficient money for complete the order"; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/Models/LineItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models 6 | { 7 | public class LineItem 8 | { 9 | public string Id { get; } 10 | public string Name { get; } 11 | public decimal Price { get; } 12 | 13 | public LineItem(string id, string name, decimal price) 14 | { 15 | Id = id; 16 | Name = name; 17 | Price = price; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/Models/Order.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models 7 | { 8 | public class Order 9 | { 10 | private readonly Dictionary _lineItems = new Dictionary(); 11 | public IReadOnlyDictionary LineItems => _lineItems; 12 | 13 | private readonly List _selectedPayments = new List(); 14 | public IReadOnlyList SelectedPayments => _selectedPayments.AsReadOnly(); 15 | 16 | private readonly List _finalizedPayments = new List(); 17 | public IReadOnlyList FinalizedPayments => _finalizedPayments.AsReadOnly(); 18 | 19 | public decimal AmountDue => _lineItems.Sum(item => item.Key.Price * item.Value) - FinalizedPayments.Sum(payment => payment.Amount); 20 | 21 | public ShippingStatus ShippingStatus { get; set; } = ShippingStatus.WaitingForPayment; 22 | 23 | public void AddLineItem(LineItem lineItem, int count) 24 | { 25 | _lineItems.Add(lineItem, count); 26 | } 27 | 28 | public void AddPayment(Payment payment) 29 | { 30 | _selectedPayments.Add(payment); 31 | } 32 | 33 | public void FinalizePayment(Payment payment) 34 | { 35 | _finalizedPayments.Add(payment); 36 | } 37 | } 38 | 39 | public enum ShippingStatus 40 | { 41 | WaitingForPayment, 42 | ReadyForShipment, 43 | Shipped 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/Models/Payment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models 6 | { 7 | public class Payment 8 | { 9 | public decimal Amount { get; set; } 10 | public PaymentProvider PaymentProvider { get; set; } 11 | } 12 | 13 | public enum PaymentProvider 14 | { 15 | Paypal, 16 | CreditCard, 17 | Invoice 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/PaymentReceivers/IReceiver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.PaymentReceivers 6 | { 7 | public interface IReceiver where T : class 8 | { 9 | void Handle(T request); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/PaymentReceivers/PaymentHandler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Exceptions; 2 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.PaymentReceivers 7 | { 8 | public class PaymentHandler 9 | { 10 | private readonly List> _receivers = new List>(); 11 | 12 | public PaymentHandler(params IReceiver[] receivers) 13 | { 14 | _receivers.AddRange(receivers); 15 | } 16 | 17 | public void Handle(Order order) 18 | { 19 | foreach (var receiver in _receivers) 20 | { 21 | Console.WriteLine($"Payment Receiver: \t {receiver.GetType().Name}"); 22 | 23 | if (order.AmountDue > 0) 24 | { 25 | receiver.Handle(order); 26 | } 27 | else 28 | { 29 | break; 30 | } 31 | } 32 | 33 | if (order.AmountDue > 0) 34 | { 35 | throw new InsufficientPaymentException(); 36 | } 37 | 38 | order.ShippingStatus = ShippingStatus.ReadyForShipment; 39 | } 40 | 41 | public PaymentHandler SetNext(IReceiver next) 42 | { 43 | _receivers.Add(next); 44 | return this; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/PaymentReceivers/PaymentHandlers/CreditCardHandler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models; 2 | using System.Linq; 3 | 4 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.PaymentReceivers.PaymentHandlers 5 | { 6 | public class CreditCardHandler : IReceiver 7 | { 8 | public void Handle(Order order) 9 | { 10 | // Invoke the Stripe API 11 | var payment = order.SelectedPayments.FirstOrDefault(x => x.PaymentProvider == PaymentProvider.CreditCard); 12 | 13 | if (payment == null) return; 14 | 15 | order.FinalizePayment(payment); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/PaymentReceivers/PaymentHandlers/InvoiceHnadler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models; 2 | using System.Linq; 3 | 4 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.PaymentReceivers.PaymentHandlers 5 | { 6 | public class InvoiceHandler : IReceiver 7 | { 8 | public void Handle(Order order) 9 | { 10 | // Create an invoice and email it 11 | 12 | var payment = order.SelectedPayments.FirstOrDefault(x => x.PaymentProvider == PaymentProvider.Invoice); 13 | 14 | if (payment == null) return; 15 | 16 | order.FinalizePayment(payment); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/ChainOfResponsibilityPattern/SeparationExample/PaymentReceivers/PaymentHandlers/PaypalHandler.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models; 2 | using System.Linq; 3 | 4 | namespace DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.PaymentReceivers.PaymentHandlers 5 | { 6 | public class PaypalHandler : IReceiver 7 | { 8 | public void Handle(Order order) 9 | { 10 | // Invoke the Paypal API to finalize payment 11 | 12 | var payment = order.SelectedPayments.FirstOrDefault(x => x.PaymentProvider == PaymentProvider.Paypal); 13 | 14 | if (payment == null) return; 15 | 16 | order.FinalizePayment(payment); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Commands/AddToCartCommand.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.CommandPattern.Models; 2 | using DesignPatterns.Behavioral.CommandPattern.Repository; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.CommandPattern.Commands 8 | { 9 | public class AddToCartCommand : ICommand 10 | { 11 | private readonly IShoppingCartRepository _shoppingCartRepo; 12 | private readonly IProductRepository _productRepo; 13 | private readonly Product _product; 14 | 15 | public AddToCartCommand(IShoppingCartRepository shoppingCartRepo, IProductRepository productRepo, Product product) 16 | { 17 | _shoppingCartRepo = shoppingCartRepo; 18 | _productRepo = productRepo; 19 | _product = product; 20 | } 21 | 22 | 23 | public void Execute() 24 | { 25 | if (_product == null) 26 | return; 27 | 28 | _productRepo.DecreaseStockBy(_product.ArticleId, 1); 29 | _shoppingCartRepo.Add(_product); 30 | } 31 | 32 | public bool CanExecute() 33 | { 34 | if (_product == null) 35 | return false; 36 | 37 | return _productRepo.GetStockFor(_product.ArticleId) > 0; 38 | } 39 | 40 | public void Undo() 41 | { 42 | if (_product == null) 43 | return; 44 | 45 | var lineItem = _shoppingCartRepo.Get(_product.ArticleId); 46 | _productRepo.IncreaseStockBy(_product.ArticleId, lineItem.Quantity); 47 | 48 | _shoppingCartRepo.RemoveAll(_product.ArticleId); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Commands/ChangeQuantityCommand.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.CommandPattern.Models; 2 | using DesignPatterns.Behavioral.CommandPattern.Repository; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.CommandPattern.Commands 8 | { 9 | public class ChangeQuantityCommand : ICommand 10 | { 11 | private readonly Operation _operation; 12 | private readonly IShoppingCartRepository _shoppingCartRepo; 13 | private readonly IProductRepository _productRepo; 14 | private readonly Product _product; 15 | 16 | public enum Operation { Increase, Decrease } 17 | 18 | public ChangeQuantityCommand(Operation operation, IShoppingCartRepository shoppingCartRepo, 19 | IProductRepository productRepo, Product product) 20 | { 21 | _operation = operation; 22 | _shoppingCartRepo = shoppingCartRepo; 23 | _productRepo = productRepo; 24 | _product = product; 25 | } 26 | 27 | public void Execute() 28 | { 29 | switch (_operation) 30 | { 31 | case Operation.Decrease: 32 | _productRepo.IncreaseStockBy(_product.ArticleId, 1); 33 | _shoppingCartRepo.DecreaseQuantity(_product.ArticleId); 34 | break; 35 | case Operation.Increase: 36 | _productRepo.DecreaseStockBy(_product.ArticleId, 1); 37 | _shoppingCartRepo.IncreaseQuantity(_product.ArticleId); 38 | break; 39 | } 40 | } 41 | 42 | public bool CanExecute() 43 | { 44 | switch (_operation) 45 | { 46 | case Operation.Decrease: 47 | return _shoppingCartRepo.Get(_product.ArticleId).Quantity != 0; 48 | case Operation.Increase: 49 | return (_productRepo.GetStockFor(_product.ArticleId) - 1) >= 0; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | public void Undo() 56 | { 57 | switch (_operation) 58 | { 59 | case Operation.Decrease: 60 | _productRepo.DecreaseStockBy(_product.ArticleId, 1); 61 | _shoppingCartRepo.IncreaseQuantity(_product.ArticleId); 62 | break; 63 | case Operation.Increase: 64 | _productRepo.IncreaseStockBy(_product.ArticleId, 1); 65 | _shoppingCartRepo.DecreaseQuantity(_product.ArticleId); 66 | break; 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Commands/CommandManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.CommandPattern.Commands 6 | { 7 | public class CommandManager 8 | { 9 | private readonly Stack _commands = new Stack(); 10 | 11 | public void Invoke(ICommand command) 12 | { 13 | if (command.CanExecute()) 14 | { 15 | _commands.Push(command); 16 | command.Execute(); 17 | } 18 | } 19 | 20 | public void Undo() 21 | { 22 | while (_commands.Count > 0) 23 | { 24 | ICommand command = _commands.Pop(); 25 | command.Undo(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Commands/ICommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.CommandPattern.Commands 6 | { 7 | public interface ICommand 8 | { 9 | void Execute(); 10 | bool CanExecute(); 11 | void Undo(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Models/Product.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.CommandPattern.Models 6 | { 7 | public class Product 8 | { 9 | public string ArticleId { get; set; } 10 | public int Quantity { get; set; } 11 | public int AmountInStock { get; set; } 12 | public string Name { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Repository/IProductRepository.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.CommandPattern.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.CommandPattern.Repository 7 | { 8 | public interface IProductRepository 9 | { 10 | void DecreaseStockBy(string id, int amount); 11 | void IncreaseStockBy(string id, int amount); 12 | int GetStockFor(string id); 13 | Product FindBy(string id); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Repository/IShoppingCartRepository.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.CommandPattern.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.CommandPattern.Repository 7 | { 8 | public interface IShoppingCartRepository 9 | { 10 | void Add(Product product); 11 | Product Get(string id); 12 | void RemoveAll(string id); 13 | void DecreaseQuantity(string id); 14 | void IncreaseQuantity(string id); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Repository/ProductsRepository.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.CommandPattern.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.CommandPattern.Repository 8 | { 9 | public class ProductsRepository : IProductRepository 10 | { 11 | private readonly List _products = new List 12 | { 13 | new Product { Name = "TLOU", ArticleId = "1", AmountInStock = 10, Quantity = 0 }, 14 | new Product { Name = "AC", ArticleId = "2", AmountInStock = 100, Quantity = 0 }, 15 | new Product { Name = "HZD", ArticleId = "3", AmountInStock = 1000, Quantity = 0 } 16 | }; 17 | 18 | public void DecreaseStockBy(string id, int amount) 19 | { 20 | _products.Where(p => p.ArticleId == id).ToList().ForEach(x => x.AmountInStock -= amount); 21 | } 22 | 23 | public void IncreaseStockBy(string id, int amount) 24 | { 25 | _products.Where(p => p.ArticleId == id).ToList().ForEach(x => x.AmountInStock += amount); 26 | } 27 | 28 | public int GetStockFor(string id) 29 | { 30 | return _products.Where(p => p.ArticleId == id).Select(x => x.AmountInStock).FirstOrDefault(); 31 | } 32 | 33 | public Product FindBy(string id) 34 | { 35 | return _products.FirstOrDefault(p => p.ArticleId == id); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/CommandPattern/Repository/ShoppingCartRepository.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.CommandPattern.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.CommandPattern.Repository 8 | { 9 | public class ShoppingCartRepository : IShoppingCartRepository 10 | { 11 | private List _products = new List(); 12 | 13 | public void Add(Product product) 14 | { 15 | if (product == null) 16 | return; 17 | 18 | _products.Add(product); 19 | } 20 | 21 | public Product Get(string id) 22 | { 23 | return _products 24 | .Where(p => p.ArticleId == id) 25 | .ToList() 26 | .FirstOrDefault(); 27 | } 28 | 29 | public void RemoveAll(string id) 30 | { 31 | _products = _products.Where(p => p.ArticleId != id).ToList(); 32 | } 33 | 34 | public void DecreaseQuantity(string id) 35 | { 36 | _products.Where(p => p.ArticleId == id).ToList().ForEach(x => x.Quantity--); 37 | } 38 | 39 | public void IncreaseQuantity(string id) 40 | { 41 | _products.Where(p => p.ArticleId == id).ToList().ForEach(x => x.Quantity++); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Mediator/Chatroom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.Mediator 6 | { 7 | public abstract class Chatroom 8 | { 9 | public abstract void Register(TeamMember member); 10 | public abstract void Send(string from, string message); 11 | // Send message to the specific objects like sending to only developers, only testers 12 | public abstract void SendTo(string from, string message) where T : TeamMember; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Mediator/Developer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.Mediator 6 | { 7 | public class Developer : TeamMember 8 | { 9 | public Developer(string name): base(name) 10 | { 11 | 12 | } 13 | 14 | public override void Receive(string from, string message) 15 | { 16 | Console.Write($"{this.Name} ({nameof(Developer)}) has received: "); 17 | base.Receive(from, message); 18 | } 19 | } 20 | 21 | public class Tester : TeamMember 22 | { 23 | public Tester(string name) : base(name) 24 | { 25 | 26 | } 27 | 28 | public override void Receive(string from, string message) 29 | { 30 | Console.Write($"{this.Name} ({nameof(Tester)}) has received: "); 31 | base.Receive(from, message); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Mediator/TeamChatroom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.Mediator 7 | { 8 | public class TeamChatroom : Chatroom 9 | { 10 | private List members = new List(); 11 | 12 | // References 13 | // just set up/register connection between mediator and colleague 14 | public override void Register(TeamMember member) 15 | { 16 | member.SetChatroom(this); 17 | this.members.Add(member); 18 | } 19 | 20 | // Sending this message for each members 21 | public override void Send(string from, string message) 22 | { 23 | this.members.ForEach(m => m.Receive(from, message)); 24 | } 25 | 26 | // Register team members at once 27 | public void RegisterMembers(params TeamMember[] teamMembers) 28 | { 29 | foreach (var member in teamMembers) 30 | { 31 | this.Register(member); 32 | } 33 | } 34 | 35 | public override void SendTo(string from, string message) 36 | { 37 | this.members.OfType().ToList().ForEach(m => m.Receive(from, message)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Mediator/TeamMember.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.Mediator 6 | { 7 | public abstract class TeamMember 8 | { 9 | public string Name { get; } 10 | private Chatroom chatroom; 11 | 12 | public TeamMember(string name) 13 | { 14 | this.Name = name; 15 | } 16 | 17 | // Set Mediator 18 | internal void SetChatroom(Chatroom chatroom) 19 | { 20 | this.chatroom = chatroom; 21 | } 22 | 23 | // Sending messages to mediator 24 | public void Send(string message) 25 | { 26 | this.chatroom.Send(this.Name, message); 27 | } 28 | // Receiving a chat message 29 | public virtual void Receive(string from, string message) 30 | { 31 | Console.WriteLine($"from {from}: '{message}'"); 32 | } 33 | 34 | public void SendTo(string message) where T : TeamMember 35 | { 36 | this.chatroom.SendTo(this.Name, message); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Observer/Interfaces/IObserver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.Observer.Interfaces 6 | { 7 | public interface IObserver 8 | { 9 | void update(string availability); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Observer/Interfaces/ISubject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.Observer.Interfaces 6 | { 7 | public interface ISubject 8 | { 9 | void RegisterObserver(IObserver observer); 10 | void RemoveObserver(IObserver observer); 11 | void NotifyObservers(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Observer/Observer.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.Observer.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.Observer 7 | { 8 | public class Observer : IObserver 9 | { 10 | public string UserName { get; set; } 11 | public Observer(string userName, ISubject subject) 12 | { 13 | UserName = userName; 14 | subject.RegisterObserver(this); 15 | } 16 | 17 | public void update(string state) 18 | { 19 | Console.WriteLine("Hello " + UserName + ", Product is now " + state + " on Amazon"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/Observer/Subject.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.Observer.Interfaces; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.Observer 7 | { 8 | public class Subject : ISubject 9 | { 10 | private List observers = new List(); 11 | private string ProductName { get; set; } 12 | private int ProductPrice { get; set; } 13 | private string State { get; set; } 14 | 15 | public Subject(string productName, int productPrice, string state) 16 | { 17 | ProductName = productName; 18 | ProductPrice = productPrice; 19 | State = state; 20 | } 21 | 22 | public string getState() 23 | { 24 | return State; 25 | } 26 | public void setState(string state) 27 | { 28 | Console.WriteLine($"Availability changed from {this.State} to {state}."); 29 | this.State = state; 30 | NotifyObservers(); 31 | } 32 | public void RegisterObserver(IObserver observer) 33 | { 34 | Console.WriteLine("Observer Added : " + ((Observer)observer).UserName); 35 | observers.Add(observer); 36 | } 37 | public void AddObservers(IObserver observer) 38 | { 39 | observers.Add(observer); 40 | } 41 | public void RemoveObserver(IObserver observer) 42 | { 43 | observers.Remove(observer); 44 | } 45 | public void NotifyObservers() 46 | { 47 | Console.WriteLine("Product Name :" 48 | + ProductName + ", product Price : " 49 | + ProductPrice + " is Now available. So notifying all Registered users "); 50 | Console.WriteLine(); 51 | foreach (IObserver observer in observers) 52 | { 53 | observer.update(State); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/StatePattern/AbstractState/IHealth.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.StatePattern.Context; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Behavioral.StatePattern.AbstractState 7 | { 8 | public interface IHealth 9 | { 10 | void DoBattle(Warrior w); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/StatePattern/Context/Warrior.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.StatePattern.AbstractState; 2 | using DesignPatterns.Behavioral.StatePattern.States; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.StatePattern.Context 8 | { 9 | public class Warrior 10 | { 11 | private IHealth health = new Normal(); //start as normal health 12 | 13 | public void Battle() 14 | { 15 | health.DoBattle(this); //calls the health to exhibit the behavior 16 | } 17 | 18 | public void SetHealth(IHealth health) 19 | { 20 | this.health = health; 21 | } 22 | 23 | public void ShowHealth() 24 | { 25 | Console.WriteLine("Warrior is now: " + health.GetType().Name); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/StatePattern/States/Normal.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.StatePattern.AbstractState; 2 | using DesignPatterns.Behavioral.StatePattern.Context; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.StatePattern.States 8 | { 9 | public class Normal : IHealth 10 | { 11 | void IHealth.DoBattle(Warrior w) 12 | { 13 | //warrior can transition to another state based on the outcome 14 | w.SetHealth(new Weak()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/StatePattern/States/Strong.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.StatePattern.AbstractState; 2 | using DesignPatterns.Behavioral.StatePattern.Context; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.StatePattern.States 8 | { 9 | public class Strong : IHealth 10 | { 11 | void IHealth.DoBattle(Warrior w) 12 | { 13 | //warrior can transition to another state based on the outcome 14 | w.SetHealth(new SuperStrong()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/StatePattern/States/SuperStrong.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.StatePattern.AbstractState; 2 | using DesignPatterns.Behavioral.StatePattern.Context; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.StatePattern.States 8 | { 9 | public class SuperStrong : IHealth 10 | { 11 | void IHealth.DoBattle(Warrior w) 12 | { 13 | //warrior can transition to another state based on the outcome 14 | w.SetHealth(new Normal()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/StatePattern/States/Weak.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.StatePattern.AbstractState; 2 | using DesignPatterns.Behavioral.StatePattern.Context; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DesignPatterns.Behavioral.StatePattern.States 8 | { 9 | public class Weak : IHealth 10 | { 11 | void IHealth.DoBattle(Warrior w) 12 | { 13 | //warrior can transition to another state based on the outcome 14 | w.SetHealth(new Strong()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/TemplateMethodPattern/AbstractLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.TemplateMethodPattern 6 | { 7 | public abstract class AbstractLogger 8 | { 9 | public void Log(object message) 10 | { 11 | string messageToLog = SerializeMessage(message); 12 | OpenDataStoreOperation(); 13 | LogMessage(messageToLog); 14 | CloseDataStoreOpreation(); 15 | } 16 | 17 | protected string SerializeMessage(object message) 18 | { 19 | Console.WriteLine("Serializing message"); 20 | return message.ToString(); 21 | } 22 | 23 | protected abstract void OpenDataStoreOperation(); 24 | 25 | protected abstract void LogMessage(string messageToLog); 26 | 27 | protected abstract void CloseDataStoreOpreation(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/TemplateMethodPattern/Loggers/DatabaseLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.TemplateMethodPattern.Loggers 6 | { 7 | public class DatabaseLogger : AbstractLogger 8 | { 9 | protected override void OpenDataStoreOperation() 10 | { 11 | Console.WriteLine("Connecting to Database."); 12 | } 13 | 14 | protected override void LogMessage(string messageToLog) 15 | { 16 | Console.WriteLine("Inserting Log Message to DB table : " + messageToLog); 17 | } 18 | 19 | protected override void CloseDataStoreOpreation() 20 | { 21 | Console.WriteLine("Closing DB connection."); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/TemplateMethodPattern/Loggers/EmailLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.TemplateMethodPattern.Loggers 6 | { 7 | public class EmailLogger : AbstractLogger 8 | { 9 | protected override void OpenDataStoreOperation() 10 | { 11 | Console.WriteLine("Connecting to mail server and logging in"); 12 | } 13 | 14 | protected override void LogMessage(string messageToLog) 15 | { 16 | Console.WriteLine("Sending Email with Log Message : " + messageToLog); 17 | } 18 | 19 | protected override void CloseDataStoreOpreation() 20 | { 21 | Console.WriteLine("Dispose Connection"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Behavioral/TemplateMethodPattern/Loggers/FileLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Behavioral.TemplateMethodPattern.Loggers 6 | { 7 | public class FileLogger : AbstractLogger 8 | { 9 | protected override void OpenDataStoreOperation() 10 | { 11 | Console.WriteLine("Opening File."); 12 | } 13 | 14 | protected override void LogMessage(string messageToLog) 15 | { 16 | Console.WriteLine("Appending Log message to file : " + messageToLog); 17 | } 18 | 19 | protected override void CloseDataStoreOpreation() 20 | { 21 | Console.WriteLine("Close File."); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Creational/FactoryMethod/BankA.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Creational.FactoryMethod 6 | { 7 | public class BankA : IBank 8 | { 9 | public string Withdraw() 10 | { 11 | return "Your request is handling by BankA"; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Creational/FactoryMethod/BankB.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Creational.FactoryMethod 6 | { 7 | public class BankB : IBank 8 | { 9 | public string Withdraw() 10 | { 11 | return "Your request is handling by BankB"; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Creational/FactoryMethod/BankFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Creational.FactoryMethod 6 | { 7 | public class BankFactory : IBankFactory 8 | { 9 | public IBank CreateBank(string bankCode) 10 | { 11 | // credit card starting numbers to define which bank belong to 12 | switch (bankCode) 13 | { 14 | case "123456": 15 | return new BankA(); 16 | case "111111": 17 | return new BankB(); 18 | default: 19 | return null; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Creational/FactoryMethod/IBank.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Creational.FactoryMethod 6 | { 7 | public interface IBank 8 | { 9 | string Withdraw(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Creational/FactoryMethod/IBankFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Creational.FactoryMethod 6 | { 7 | public interface IBankFactory 8 | { 9 | IBank CreateBank(string bankCode); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Creational/Singleton/AppSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Creational.Singleton 6 | { 7 | class AppSettings 8 | { 9 | // the class variable is null if no instance is instantiated 10 | private static AppSettings Instance = null; 11 | private AppSettings() {} 12 | 13 | public static AppSettings GetInstance() 14 | { 15 | if (Instance == null) 16 | { 17 | Instance = new AppSettings(); 18 | } 19 | return Instance; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Creational/Singleton/Counter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Creational.Singleton 6 | { 7 | public class Counter 8 | { 9 | // The sole instance of the class 10 | private static Counter instance = null; 11 | 12 | public int count = 0; 13 | // just for locking this object to solve multi-threading problem 14 | private static object lockObj = new object(); 15 | 16 | // Make the constructor private so its only accessible to members of the class. 17 | private Counter(){} 18 | 19 | // Create a static method for object creation 20 | public static Counter GetInstance() 21 | { 22 | // Only instantiate the object when needed, to save memory recourses 23 | // Lazy Initialization 24 | // Double-checked locking 25 | if (instance == null) 26 | { 27 | lock(lockObj) 28 | { 29 | if (instance == null) 30 | { 31 | instance = new Counter(); 32 | } 33 | } 34 | } 35 | 36 | return instance; 37 | } 38 | 39 | public void AddOne(){count++;} 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/DesignPatterns.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Program.cs: -------------------------------------------------------------------------------- 1 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.Models; 2 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.PaymentReceivers; 3 | using DesignPatterns.Behavioral.ChainOfResponsibilityPattern.SeparationExample.PaymentReceivers.PaymentHandlers; 4 | using DesignPatterns.Behavioral.CommandPattern.Commands; 5 | using DesignPatterns.Behavioral.Mediator; 6 | using DesignPatterns.Behavioral.CommandPattern.Repository; 7 | using DesignPatterns.Behavioral.StatePattern.Context; 8 | using DesignPatterns.Behavioral.TemplateMethodPattern; 9 | using DesignPatterns.Behavioral.TemplateMethodPattern.Loggers; 10 | using DesignPatterns.Creational.FactoryMethod; 11 | using DesignPatterns.Creational.Singleton; 12 | using DesignPatterns.Structural.AdapterPattern; 13 | using DesignPatterns.Structural.CompositePattern; 14 | using DesignPatterns.Structural.DecoratorPattern; 15 | using DesignPatterns.Structural.DecoratorPattern.Decorators; 16 | using DesignPatterns.Structural.FacadePattern; 17 | using DesignPatterns.Structural.ProxyPattern; 18 | using System; 19 | using System.Collections; 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | using System.Text; 23 | using DesignPatterns.Behavioral.Observer; 24 | 25 | namespace DesignPattern 26 | { 27 | class Program 28 | { 29 | static void Main(string[] args) 30 | { 31 | // Creational Design Pattern 32 | 33 | #region SingletonPattern 34 | //Counter counter1 = Counter.GetInstance(); 35 | //Counter counter2 = Counter.GetInstance(); 36 | //counter1.AddOne(); 37 | //counter2.AddOne(); 38 | 39 | //Console.WriteLine("counter 1:" + counter1.count.ToString()); 40 | //Console.WriteLine("counter 2:" + counter2.count.ToString()); 41 | //Console.WriteLine(); 42 | 43 | //counter1.AddOne(); 44 | //Console.WriteLine("counter 1:" + counter1.count.ToString()); 45 | //Console.WriteLine("counter 2:" + counter2.count.ToString()); 46 | #endregion 47 | 48 | #region FactoryMethodPattern 49 | 50 | //Console.WriteLine("Enter your card number"); 51 | //var cardNumber = Console.ReadLine(); 52 | //var bankCard = cardNumber.Substring(0, 6); 53 | 54 | //// Create bank object from the factory 55 | //BankFactory bankFactory = new BankFactory(); 56 | //IBank bank = bankFactory.CreateBank(bankCard); 57 | 58 | //Console.WriteLine(bank.Withdraw()); 59 | 60 | #endregion 61 | 62 | // Structural Design Pattern 63 | 64 | #region FacadePattern 65 | 66 | //ShoppingBasket basket = new ShoppingBasket(); 67 | //basket.AddItem(new BasketItem { ItemId = "132", ItemPrice = 59, Quantity = 3 }); 68 | //basket.AddItem(new BasketItem { ItemId = "456", ItemPrice = 49, Quantity = 2 }); 69 | //basket.AddItem(new BasketItem { ItemId = "789", ItemPrice = 39, Quantity = 1 }); 70 | 71 | //// Facade class within the client without knowing the process complexity 72 | //// Hiding information 73 | //PurchaseOrder order = new PurchaseOrder(); 74 | 75 | //order.CreateOrder(basket, "name:aboelkassem,bank:1526465,mobile:01154321101"); 76 | 77 | #endregion 78 | 79 | #region AdapterPattern 80 | ///// 81 | ///// The Client Class to pass array of employees 82 | ///// 83 | //string[,] employeesArray = new string[5,4] 84 | //{ 85 | // {"101","John","SE","10000"}, 86 | // {"102","Smith","SE","20000"}, 87 | // {"103","Dev","SSE","30000"}, 88 | // {"104","Pam","SE","40000"}, 89 | // {"105","Sara","SSE","50000"} 90 | //}; 91 | 92 | //ITarget target = new EmployeeAdapter(); 93 | //Console.WriteLine("HR system passes employee string array to Adapter\n"); 94 | //target.ProcessCompanySalary(employeesArray); 95 | #endregion 96 | 97 | #region CompositePattern 98 | //// example of virtual file system 99 | //// making directory as composite object and file as leaf 100 | //// this is the client 101 | 102 | //var root = new DirectoryItem("development"); 103 | //var proj1 = new DirectoryItem("project1"); 104 | //var proj2 = new DirectoryItem("project2"); 105 | //root.Add(proj1); 106 | //root.Add(proj2); 107 | 108 | //proj1.Add(new FileItem("p1f1.txt", 2100)); 109 | //proj1.Add(new FileItem("p1f2.txt", 3100)); 110 | 111 | //var subDir1 = new DirectoryItem("sub-dir1"); 112 | //subDir1.Add(new FileItem("p1f3.txt", 4100)); 113 | //subDir1.Add(new FileItem("p1f4.txt", 5100)); 114 | //proj1.Add(subDir1); 115 | 116 | //proj2.Add(new FileItem("p2f1.txt", 6100)); 117 | //proj2.Add(new FileItem("p2f2.txt", 7100)); 118 | 119 | //Console.WriteLine($"Total size (root): {root.GetSizeInKB()}KB"); 120 | //Console.WriteLine($"Total size (proj1): {proj1.GetSizeInKB()}KB"); 121 | //Console.WriteLine($"Total size (proj2): {proj2.GetSizeInKB()}KB"); 122 | #endregion 123 | 124 | #region ProxyPattern 125 | 126 | //SMSServiceProxy proxy = new SMSServiceProxy(); 127 | //Console.WriteLine(proxy.SendSMS("123", "01154321101", "message 1")); 128 | //Console.WriteLine(proxy.SendSMS("123", "01154321101", "message 2")); 129 | //Console.WriteLine(proxy.SendSMS("123", "01154321101", "message 3")); 130 | 131 | #endregion 132 | 133 | #region DecoratorPattern 134 | 135 | //bool smsNotificationEnabled = false; 136 | //bool whatsAppNotificationEnabled = true; 137 | //INotifier notifier = new EmailNotifier("mohamedabdelrahman9972@gmail.com"); 138 | 139 | //// Adding SMS Notification to emailing service 140 | //if (smsNotificationEnabled) 141 | //{ 142 | // notifier = new SMSNotifierDecorator(notifier, "01154321101"); 143 | //} 144 | 145 | //// Adding WhatsApp Notification to emailing service 146 | //if (whatsAppNotificationEnabled) 147 | //{ 148 | // notifier = new WhatsAppNotifierDecorator(notifier, "01154321101"); 149 | //} 150 | 151 | //// Default that is sending Email 152 | //notifier.notify(); 153 | 154 | #endregion 155 | 156 | // Behavioral Design Pattern 157 | #region TemplateMethodPattern 158 | //AbstractLogger fileLogger = new FileLogger(); 159 | //fileLogger.Log("Message to Log in File."); 160 | 161 | //AbstractLogger emailLogger = new EmailLogger(); 162 | //emailLogger.Log("Message to Log via Email."); 163 | 164 | //AbstractLogger databaseLogger = new DatabaseLogger(); 165 | //databaseLogger.Log("Message to Log in DB."); 166 | #endregion 167 | 168 | #region ChainOfResponsibilityPattern 169 | //var order = new Order(); 170 | //order.AddLineItem(new LineItem("GUID 1", "Product Name One", 499), 2); 171 | //order.AddLineItem(new LineItem("GUID 2", "Product Name Two", 799), 1); 172 | 173 | //order.AddPayment(new Payment 174 | //{ 175 | // PaymentProvider = PaymentProvider.Paypal, 176 | // Amount = 1000 177 | //}); 178 | 179 | //order.AddPayment(new Payment 180 | //{ 181 | // PaymentProvider = PaymentProvider.Invoice, 182 | // Amount = 797 183 | //}); 184 | 185 | //Console.WriteLine($"Amount Due: \t {order.AmountDue}"); 186 | //Console.WriteLine($"Shipping Status: \t {order.ShippingStatus}"); 187 | //Console.WriteLine(); 188 | 189 | //// chain of responsibilities with OOP No Separation Example 190 | //// var handler = new PaypalHandler(); 191 | //// handler.SetNext(new CreditCardHandler()) 192 | //// .SetNext(new InvoiceHandler()); 193 | 194 | //// handler.Handle(order); 195 | 196 | //// chain of responsibilities with OOP Separation Example 197 | //var handler = new PaymentHandler() 198 | // .SetNext(new PaypalHandler()) 199 | // .SetNext(new InvoiceHandler()) 200 | // .SetNext(new CreditCardHandler()); 201 | //handler.Handle(order); 202 | 203 | //Console.WriteLine($"Amount Due: \t {order.AmountDue}"); 204 | //Console.WriteLine($"Shipping Status: \t {order.ShippingStatus}"); 205 | #endregion 206 | 207 | #region StatePattern 208 | //// Context is you have warrior and every battle taken he get stronger 209 | //// his states changes 210 | //Warrior w = new Warrior(); 211 | //w.ShowHealth(); 212 | 213 | //w.Battle(); 214 | //w.ShowHealth(); 215 | 216 | //w.Battle(); 217 | //w.ShowHealth(); 218 | 219 | //w.Battle(); 220 | //w.ShowHealth(); 221 | 222 | //w.Battle(); 223 | //w.ShowHealth(); 224 | 225 | #endregion 226 | 227 | #region CommandPattern 228 | //var shoppingCartRepo = new ShoppingCartRepository(); 229 | //var productsRepo = new ProductsRepository(); 230 | 231 | //var product = productsRepo.FindBy("1"); 232 | 233 | //var addToCartCommand = new AddToCartCommand(shoppingCartRepo, productsRepo, product); 234 | //var increaseQuantityCommand = new ChangeQuantityCommand( 235 | // ChangeQuantityCommand.Operation.Increase, 236 | // shoppingCartRepo, 237 | // productsRepo, 238 | // product); 239 | 240 | //var manager = new CommandManager(); 241 | //manager.Invoke(addToCartCommand); 242 | //manager.Invoke(increaseQuantityCommand); 243 | //manager.Invoke(increaseQuantityCommand); 244 | //manager.Invoke(increaseQuantityCommand); 245 | //manager.Invoke(increaseQuantityCommand); 246 | 247 | //PrintCart(shoppingCartRepo); 248 | 249 | //// undoing all shopping products/commands to back to stock 250 | //manager.Undo(); 251 | 252 | //PrintCart(shoppingCartRepo); 253 | 254 | //void PrintCart(ShoppingCartRepository repo) 255 | //{ 256 | // if (repo == null) throw new ArgumentNullException(nameof(repo)); 257 | 258 | // var p = repo.Get(product.ArticleId); 259 | 260 | // if (p == null) 261 | // { 262 | // Console.WriteLine(); 263 | // Console.WriteLine("Your cart is empty"); 264 | // return; 265 | // } 266 | 267 | // Console.WriteLine("In your cart is the following item: "); 268 | // Console.WriteLine($"Product name: { p.Name }"); 269 | // Console.WriteLine($"Amount in stock: {p.AmountInStock}"); 270 | // Console.WriteLine($"Quantity in basket: {p.Quantity}"); 271 | //} 272 | 273 | #endregion 274 | 275 | #region MediatorPattern 276 | //var teamChat = new TeamChatroom(); 277 | 278 | //var mohamed = new Developer("Mohamed"); 279 | //var ahmed = new Developer("Ahmed"); 280 | //var shimaa = new Tester("Shimaa"); 281 | //var sara = new Tester("Sara"); 282 | 283 | //teamChat.RegisterMembers(mohamed, ahmed, shimaa, sara); 284 | 285 | //mohamed.Send("Hey everyone, i'm mohamed, lets get some fun"); 286 | //Console.WriteLine(); 287 | //shimaa.Send("Oh, i have found issue while i testing your app"); 288 | //Console.WriteLine(); 289 | 290 | //// developer objects will only receive this message 291 | //ahmed.SendTo("hey developers, i have bug i cannot fix it, anyone can help?"); 292 | #endregion 293 | 294 | #region ObserverPattern 295 | ////Create a Product with Out Of Stock Status 296 | //Subject RedMI = new Subject("Red MI Mobile", 10000, "Out Of Stock"); 297 | 298 | //Observer user1 = new Observer("Mohamed", RedMI); 299 | //Observer user2 = new Observer("Ahmed", RedMI); 300 | //Observer user3 = new Observer("Ali", RedMI); 301 | 302 | //Console.WriteLine("Red MI Mobile current state : " + RedMI.getState()); 303 | //Console.WriteLine(); 304 | //// Now product is available 305 | //RedMI.setState("Available"); 306 | #endregion 307 | } 308 | } 309 | } -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/AdapterPattern/Employee.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.AdapterPattern 6 | { 7 | public class Employee 8 | { 9 | public int ID { get; set; } 10 | public string Name { get; set; } 11 | public string Designation { get; set; } 12 | public decimal Salary { get; set; } 13 | 14 | public Employee(int id, string name, string designation, decimal salary) 15 | { 16 | ID = id; 17 | Name = name; 18 | Designation = designation; 19 | Salary = salary; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/AdapterPattern/EmployeeAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.AdapterPattern 6 | { 7 | /// 8 | /// Adapter Class to handle everything of converting and make it compatible 9 | /// 10 | public class EmployeeAdapter: ThirdPartyBillingSystem, ITarget 11 | { 12 | public void ProcessCompanySalary(string[,] employeesArray) 13 | { 14 | string Id = null; 15 | string Name = null; 16 | string Designation = null; 17 | string Salary = null; 18 | List listEmployee = new List(); 19 | 20 | for (int i = 0; i < employeesArray.GetLength(0); i++) 21 | { 22 | for (int j = 0; j < employeesArray.GetLength(1); j++) 23 | { 24 | if (j == 0) 25 | { 26 | Id = employeesArray[i, j]; 27 | } 28 | else if (j == 1) 29 | { 30 | Name = employeesArray[i, j]; 31 | } 32 | else if (j == 1) 33 | { 34 | Designation = employeesArray[i, j]; 35 | } 36 | else 37 | { 38 | Salary = employeesArray[i, j]; 39 | } 40 | } 41 | listEmployee.Add(new Employee(Convert.ToInt32(Id), Name, Designation, Convert.ToDecimal(Salary))); 42 | } 43 | Console.WriteLine("Adapter converted Array of Employee to List of Employee"); 44 | Console.WriteLine("Then delegate to the ThirdPartyBillingSystem for processing the employee salary\n"); 45 | ProcessSalary(listEmployee); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/AdapterPattern/ITarget.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.AdapterPattern 6 | { 7 | /// 8 | /// target interface to be implemented in adapter class 9 | /// 10 | public interface ITarget 11 | { 12 | void ProcessCompanySalary(string[,] employeesArray); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/AdapterPattern/ThirdPartyBillingSystem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.AdapterPattern 6 | { 7 | /// 8 | /// Service/Adaptee Class 9 | /// 10 | public class ThirdPartyBillingSystem 11 | { 12 | //ThirdPartyBillingSystem accepts employees information as a List to process each employee salary List 13 | public void ProcessSalary(List listEmployee) 14 | { 15 | foreach (Employee employee in listEmployee) 16 | { 17 | Console.WriteLine("Rs." + employee.Salary + " Salary Credited to " + employee.Name + " Account"); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/CompositePattern/DirectoryItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Structural.CompositePattern 7 | { 8 | // Composite Class 9 | public class DirectoryItem : FileSystemItem 10 | { 11 | public List Items { get; } = new List(); 12 | 13 | public DirectoryItem(string name) : base(name) 14 | { 15 | } 16 | 17 | public void Add(FileSystemItem component) 18 | { 19 | this.Items.Add(component); 20 | } 21 | 22 | public void Remove(FileSystemItem component) 23 | { 24 | this.Items.Remove(component); 25 | } 26 | 27 | public override decimal GetSizeInKB() 28 | { 29 | // get the size of all it's children 30 | return this.Items.Sum(x => x.GetSizeInKB()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/CompositePattern/FileItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.CompositePattern 6 | { 7 | // Leaf class 8 | public class FileItem : FileSystemItem 9 | { 10 | public long FileBytes { get; } 11 | 12 | public FileItem(string name, long fileBytes) : base(name) 13 | { 14 | this.FileBytes = fileBytes; 15 | } 16 | 17 | public override decimal GetSizeInKB() 18 | { 19 | return decimal.Divide(this.FileBytes, 1000); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/CompositePattern/FileSystemItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.CompositePattern 6 | { 7 | // Base Component 8 | public abstract class FileSystemItem 9 | { 10 | public string Name { get; } 11 | 12 | public FileSystemItem(string name) 13 | { 14 | this.Name = name; 15 | } 16 | 17 | public abstract decimal GetSizeInKB(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/DecoratorPattern/Decorators/SMSNotifierDecorator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.DecoratorPattern.Decorators 6 | { 7 | public class SMSNotifierDecorator : NotifierDecorator 8 | { 9 | protected string phoneNumber; 10 | 11 | public SMSNotifierDecorator(INotifier notifier, string phoneNumber) : base(notifier) 12 | { 13 | this.phoneNumber = phoneNumber; 14 | } 15 | 16 | public void SendSMS() 17 | { 18 | Console.WriteLine($"Sending SMS to: {phoneNumber}"); 19 | Console.WriteLine($"You latest operation was executed successfully"); 20 | } 21 | 22 | public override void notify() 23 | { 24 | base.notify(); 25 | this.SendSMS(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/DecoratorPattern/Decorators/WhatsAppNotifierDecorator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.DecoratorPattern.Decorators 6 | { 7 | public class WhatsAppNotifierDecorator : NotifierDecorator 8 | { 9 | protected string phoneNumber; 10 | 11 | public WhatsAppNotifierDecorator(INotifier notifier, string phoneNumber) : base(notifier) 12 | { 13 | this.phoneNumber = phoneNumber; 14 | } 15 | 16 | public void SendSMS() 17 | { 18 | Console.WriteLine($"Sending WhatsApp message to: {phoneNumber}"); 19 | Console.WriteLine($"You latest operation was executed successfully"); 20 | } 21 | 22 | public override void notify() 23 | { 24 | base.notify(); 25 | this.SendSMS(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/DecoratorPattern/EmailNotifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.DecoratorPattern 6 | { 7 | public class EmailNotifier : INotifier 8 | { 9 | public string email; 10 | 11 | public EmailNotifier(string email) 12 | { 13 | this.email = email; 14 | } 15 | 16 | public void notify() 17 | { 18 | Console.WriteLine($"Sending email to: {email}"); 19 | Console.WriteLine($"You latest operation was executed successfully"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/DecoratorPattern/INotifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.DecoratorPattern 6 | { 7 | public interface INotifier 8 | { 9 | public void notify(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/DecoratorPattern/NotifierDecorator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.DecoratorPattern 6 | { 7 | public abstract class NotifierDecorator : INotifier 8 | { 9 | protected INotifier notifier; 10 | 11 | public NotifierDecorator(INotifier notifier) 12 | { 13 | this.notifier = notifier; 14 | } 15 | 16 | public virtual void notify() 17 | { 18 | this.notifier.notify(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/BasketItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | public class BasketItem 8 | { 9 | public string ItemId { get; set; } 10 | public double ItemPrice { get; set; } 11 | public double Quantity { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/Inventory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | public class Inventory 8 | { 9 | public bool CheckItemQuantity(string itemId, double quantity) 10 | { 11 | return quantity < 100; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/InventoryOrder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | public class InventoryOrder 8 | { 9 | public string CreateOrder(ShoppingBasket basket, string storeId) 10 | { 11 | basket.GetItems(); 12 | return $"Order Number is {System.Guid.NewGuid().ToString()}"; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/PaymentProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | public class PaymentProcessor 8 | { 9 | public bool HandlePayment(double amount, string bankInfo) 10 | { 11 | return true; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/PurchaseInvoice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | public class PurchaseInvoice 8 | { 9 | public double discount = 0; 10 | public double totalAmount = 0; 11 | public double netTotal = 0; 12 | 13 | public PurchaseInvoice CreateInvoice(ShoppingBasket basket, string customerInfo) 14 | { 15 | var invoice = new PurchaseInvoice(); 16 | var items = basket.GetItems(); 17 | foreach (var item in items) 18 | { 19 | invoice.totalAmount += item.ItemPrice * item.Quantity; 20 | } 21 | 22 | // apply discount 23 | if (items.Count > 5) 24 | { 25 | invoice.discount = 20; 26 | } 27 | 28 | invoice.netTotal = invoice.totalAmount - invoice.discount; 29 | return invoice; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/PurchaseOrder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | // This is the Facade Class to handle all shopping processes with easy interface 8 | public class PurchaseOrder 9 | { 10 | public bool CreateOrder(ShoppingBasket basket, string custInfo) 11 | { 12 | // Check stock 13 | bool isAvailable = true; 14 | Inventory inventory = new Inventory(); 15 | 16 | foreach (var item in basket.GetItems()) 17 | { 18 | if (!inventory.CheckItemQuantity(item.ItemId, item.Quantity)) 19 | { 20 | isAvailable = false; 21 | } 22 | } 23 | 24 | if (isAvailable) 25 | { 26 | // Create Inventory Order 27 | InventoryOrder inventoryOrder = new InventoryOrder(); 28 | inventoryOrder.CreateOrder(basket, "123"); 29 | 30 | // Create Invoice 31 | PurchaseInvoice invoice = new PurchaseInvoice(); 32 | var inv = invoice.CreateInvoice(basket, "address:123,id=6546,email=xyz"); 33 | 34 | // Payment 35 | PaymentProcessor payment = new PaymentProcessor(); 36 | payment.HandlePayment(inv.netTotal, "acc=123456879"); 37 | 38 | // Send SMS 39 | SmsNotofications sms = new SmsNotofications(); 40 | sms.SendSms("132", "Invoice Created"); 41 | 42 | return true; 43 | } 44 | else 45 | { 46 | return false; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/ShoppingBasket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | public class ShoppingBasket 8 | { 9 | private List _items = new List(); 10 | 11 | public void AddItem(BasketItem item) 12 | { 13 | _items.Add(item); 14 | } 15 | 16 | public void RemoveItem(string itemId) 17 | { 18 | var item = _items.Find(s => s.ItemId == itemId); 19 | if (item.Quantity > 0) 20 | item.Quantity = item.Quantity - 1; 21 | } 22 | 23 | public List GetItems() 24 | { 25 | return _items; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/FacadePattern/SmsNotofications.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.FacadePattern 6 | { 7 | public class SmsNotofications 8 | { 9 | public void SendSms(string to, string msg) 10 | { 11 | // send sms 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/ProxyPattern/ConcereteSMSService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.ProxyPattern 6 | { 7 | /// 8 | /// Real Subject class 9 | /// 10 | public class ConcereteSMSService : ISMSService 11 | { 12 | public string SendSMS(string custId, string mobile, string sms) 13 | { 14 | return $"CustomerId {custId},the message {sms}, had sent to {mobile} successfully"; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/ProxyPattern/ISMSService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DesignPatterns.Structural.ProxyPattern 6 | { 7 | /// 8 | /// the Subject interface 9 | /// you can make it abstract class if there is a configuration 10 | /// or additional code implemented 11 | /// 12 | public interface ISMSService 13 | { 14 | public string SendSMS(string custId, string mobile, string sms); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPattern/Structural/ProxyPattern/SMSServiceProxy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DesignPatterns.Structural.ProxyPattern 7 | { 8 | /// 9 | /// The proxy class to handle checking, counting, addressing and any needed operations 10 | /// for every customer using SMS service 11 | /// 12 | public class SMSServiceProxy : ISMSService 13 | { 14 | // if calls for each customer > 100 don't send request to SMS service class 15 | 16 | //private ConcereteSMSService _smsService; 17 | private ISMSService _smsService; 18 | // Database 19 | private Dictionary _smsCount = new Dictionary(); 20 | 21 | public string SendSMS(string custId, string mobile, string sms) 22 | { 23 | if (_smsService == null) 24 | _smsService = new ConcereteSMSService(); 25 | 26 | // first call for this customer 27 | if (!_smsCount.ContainsKey(custId)) 28 | { 29 | _smsCount.Add(custId, 1); 30 | return _smsService.SendSMS(custId, mobile, sms); 31 | } 32 | else 33 | { 34 | var customer = _smsCount.Where(x => x.Key == custId).FirstOrDefault(); 35 | if (customer.Value >= 100) 36 | { 37 | return "You have reached the maximum send messages for this subscription"; 38 | } 39 | else 40 | { 41 | _smsCount[custId] = customer.Value + 1; 42 | return _smsService.SendSMS(custId, mobile, sms); 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/DesignPattern/DesignPatterns.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30711.63 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns", "DesignPattern\DesignPatterns.csproj", "{91CCCF0A-A32F-489C-8D55-934A9C6D32CC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {91CCCF0A-A32F-489C-8D55-934A9C6D32CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {91CCCF0A-A32F-489C-8D55-934A9C6D32CC}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {91CCCF0A-A32F-489C-8D55-934A9C6D32CC}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {91CCCF0A-A32F-489C-8D55-934A9C6D32CC}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9510CD76-DDD3-45ED-AC28-A5B46F046F4F} 24 | EndGlobalSection 25 | EndGlobal 26 | --------------------------------------------------------------------------------