{"id":26489416,"url":"https://github.com/htmujahid/software-design-patterns","last_synced_at":"2026-02-19T00:02:06.622Z","repository":{"id":114205491,"uuid":"601990712","full_name":"htmujahid/Software-Design-Patterns","owner":"htmujahid","description":"Software Engineering","archived":false,"fork":false,"pushed_at":"2023-08-05T07:08:22.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-22T17:46:05.099Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/htmujahid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-02-15T09:09:21.000Z","updated_at":"2023-08-05T07:04:11.000Z","dependencies_parsed_at":"2023-06-25T23:49:17.391Z","dependency_job_id":null,"html_url":"https://github.com/htmujahid/Software-Design-Patterns","commit_stats":null,"previous_names":["htmujahid/software-design-patterns"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/htmujahid/Software-Design-Patterns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/htmujahid%2FSoftware-Design-Patterns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/htmujahid%2FSoftware-Design-Patterns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/htmujahid%2FSoftware-Design-Patterns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/htmujahid%2FSoftware-Design-Patterns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/htmujahid","download_url":"https://codeload.github.com/htmujahid/Software-Design-Patterns/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/htmujahid%2FSoftware-Design-Patterns/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29599338,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T22:25:43.180Z","status":"ssl_error","status_checked_at":"2026-02-18T22:25:42.766Z","response_time":162,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-20T07:23:38.230Z","updated_at":"2026-02-19T00:02:06.526Z","avatar_url":"https://github.com/htmujahid.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"_Software Design and Architecture_\n\n-   [Introduction](#introduction)\n-   [Software Design Process](#object-oriented-design)\n-   [Software Design Process](#software-design-process)\n    -   [Cohesion](#cohesion)\n    -   [Coupling](#coupling)\n-   [Software Design Principles](#software-design-principles)\n    -   [Single Responsibility Principle](#single-responsibility-principle)\n    -   [Open-Close Principle](#open-close-principle)\n    -   [Liskov Substitution Principle](#liskov-substitution-principle)\n    -   [Interface Segregation Principle](#interface-segregation-principle)\n    -   [Dependency Inversion Principle](#dependency-inversion-principle)\n    -   [Package Level Software Design Principle](#package-level-software-design-principles)\n    -   [Release Reuse Equibalency Principle](#release-reuse-equibalency-principle)\n    -   [Commono Closure Principle](#common-clousure-principle)\n    -   [Common Reuse Principe](#common-reuse-principle)\n    -   [Acyclic Dependencies Principe](#acyclic-dependencies-principle)\n    -   [Stable Depencies Principle](#stable-dependcies-principle)\n-   [Software Design Patterns](#software-design-patterns)\n    -   [Creational Design Patterns](#creational-design-patterns)\n        -   [Singleton Pattern](#singleton-pattern)\n        -   [Facade Pattern](#facade-pattern)\n        -   [Abstract Factory Pattern](#abstract-factory-pattern)\n        -   [Builder Pattern](#builder-pattern)\n        -   [Prototype Pattern](#prototype-pattern)\n        -   [Object Pool Pattern](#object-pool-pattern)\n    -   [Structural Design Patterns](#structural-design-patterns)\n        -   [Adapter Pattern](#adapter-pattern)\n        -   [Bridge Pattern](#bridge-pattern)\n        -   [Composite Pattern](#composite-pattern)\n        -   [Decorator Pattern](#decorator-pattern)\n        -   [Facade Pattern](#facade-pattern)\n        -   [Flyweight Pattern](#flyweight-pattern)\n        -   [Proxy Pattern](#proxy-pattern))\n    -   [Behavioral Design Patterns](#behavioral-design-patterns)\n        -   [Chain of Responsibility Pattern](#chain-of-responsiblity-pattern)\n        -   [Command Pattern](#command-pattern)\n        -   [Observer Pattern](#observer-pattern)\n        -   [Iterator Pattern](#iterator-pattern)\n        -   [State Pattern](#state-pattern)\n        -   [Visitor Pattern](#visitor-pattern)\n        -   [Mediator Pattern](#mediator-pattern)\n        -   [Memento Pattern](#memento-pattern)\n        -   [Strategy Pattern](#strategy-pattern)\n        -   [Template Method Pattern](#template-metohd-pattern)\n-   [Software Architectural Patterns](#software-architectural-patterns)\n    -   [Model View Controller Architecture](#model-view-controller-architecture)\n    -   [Layered Architectured](#layered-architecture)\n    -   [Enterprise Architecture](#enterprise-architecture)\n    -   [Business Architecture](#business-architecture)\n    -   [Information System Architecture](#information-system-architecture)\n    -   [Application Architecture and Data Architecture](#application-architecture--data-architecture)\n\n# Introduction\n\nSoftware design refers to the process of creating a plan for a software application's structure, functionality, and features. It includes determining the software's requirements, identifying the design patterns to be used, and creating a detailed design specification.\n\nSoftware architecture refers to the overall structure and organization of a software application, including its components, modules, and their interactions. It involves designing a high-level view of the software application's system, which includes defining the software's interfaces, data flows, and communication patterns.\n\nSoftware design and architecture are crucial in ensuring that software applications are scalable, maintainable, and reliable. They help software developers create software applications that are efficient, secure, and meet the needs of end-users.\n\n# Object Oriented Design\n\nObject-oriented programming (OOP) is a programming paradigm that revolves around the concept of objects, which are instances of classes that encapsulate data and behavior. OOP emphasizes code organization, reuse, and maintainability, making it a popular choice for developing large-scale applications.\n\nIn OOP, classes define the blueprint for creating objects, and objects are created from these classes using the new operator. A class consists of data members, which represent the object's attributes or state, and member functions, which represent the object's behavior or methods.\n\nOOP has four main principles: encapsulation, inheritance, polymorphism, and abstraction.\n\n-   Encapsulation: Encapsulation is the practice of hiding the implementation details of a class and exposing only the necessary interface to the user. This allows for better code organization, improves code maintainability, and reduces the risk of accidental modification.\n\n-   Inheritance: Inheritance is the process of creating new classes that inherit properties and behaviors from existing classes. This allows for code reuse and enables the creation of more specialized classes.\n\n-   Polymorphism: Polymorphism allows objects of different classes to be treated as if they were of the same class, enabling code to be written that can work with objects in a more generic way. Polymorphism can be achieved through method overriding and method overloading.\n\n-   Abstraction: Abstraction is the practice of focusing on the essential features of an object and ignoring its non-essential details. This allows for a simpler and more maintainable codebase.\n\nOne of the main advantages of OOP is that it enables modular programming, allowing developers to break down large problems into smaller, more manageable ones. Additionally, OOP allows for code reuse, as classes and objects can be easily used in multiple parts of an application.\n\n# Software Design Process\n\nThe software design process is a series of steps that software developers follow to create a detailed plan for building a software application. It typically involves analyzing requirements, creating a high-level design, refining the design through iterations, and creating a detailed design specification that guides the implementation process. The software design process also includes reviewing and testing the design to ensure that it meets the software's functional and non-functional requirements.\n\n## Cohesion\n\nCohesion refers to the degree to which the elements within a module or component work together to achieve a single purpose. In other words, it measures how well the responsibilities of a module are aligned and how focused its functionality is. A highly cohesive module is one that has a single, well-defined purpose and contains related functions.\n\n```cpp\n// A class with high cohesion, containing methods that are all related to mathematical operations\n\nclass MathOperations {\npublic:\n    double square(double x) {\n        return x * x;\n    }\n\n    double cube(double x) {\n        return x * x * x;\n    }\n\n    double power(double x, int n) {\n        double result = 1;\n        for (int i = 0; i \u003c n; i++) {\n            result *= x;\n        }\n        return result;\n    }\n};\n```\n\nIn the above example, all the methods within the MathOperations class are related to mathematical operations, and the class has a clear and well-defined purpose.\n\n## Coupling\n\nCoupling, on the other hand, refers to the degree to which different modules or components depend on each other. Low coupling indicates that modules are loosely connected, and changes in one module do not have a significant impact on other modules. High coupling, on the other hand, indicates that modules are tightly connected, and changes in one module can have a significant impact on other modules.\n\n```cpp\n// A class with high coupling, where a change in one class requires changes in another class\n\nclass Customer {\npublic:\n    Customer(string name, string email) : name(name), email(email) {}\n    string getName() {\n        return name;\n    }\n    string getEmail() {\n        return email;\n    }\nprivate:\n    string name;\n    string email;\n};\n\nclass Order {\npublic:\n    Order(Customer customer, vector\u003cstring\u003e items) : customer(customer), items(items) {}\n    string getCustomerName() {\n        return customer.getName();\n    }\n    string getCustomerEmail() {\n        return customer.getEmail();\n    }\nprivate:\n    Customer customer;\n    vector\u003cstring\u003e items;\n};\n```\n\nIn the above example, the Order class is tightly coupled to the Customer class. If the Customer class changes, it could potentially affect the Order class, which is not ideal. A better approach would be to use a simpler data structure like a struct to represent the customer, so that the Order class is less dependent on the Customer class.\n\nDesigning software components with high cohesion and low coupling is important to create software that is modular, flexible, and easy to maintain. Therefore, understanding and managing cohesion and coupling is an important part of the software design process.\n\n# Software Design Principles\n\nSoftware design principles are guidelines or rules that software designers follow to create software that is well-structured, maintainable, and extensible. These principles are based on best practices and lessons learned from experience in software development.\n\n## Single Responsibility Principle\n\nThe SRP states that a class should have only one responsibility or reason to change. This means that a class should only have one job, and if that job changes, the class should be modified accordingly. For example:\n\n```cpp\nclass Shape {\npublic:\n    virtual double area() const = 0;\n};\n\nclass Circle : public Shape {\npublic:\n    double area() const override { /_ ... _/ }\n};\n\nclass Rectangle : public Shape {\npublic:\n    double area() const override { /_ ... _/ }\n};\n```\n\nIn this example, the Shape class has a single responsibility: to define a shape with an area. The Circle and Rectangle classes inherit from Shape and implement the area calculation specific to their shape.\n\n## Open-Close Principle\n\nThe OCP states that software entities should be open for extension, but closed for modification. This means that existing code should not be modified to add new features, but instead should be extended through inheritance, composition, or other means. For example:\n\n```cpp\nclass Logger {\npublic:\n    virtual void log(const std::string\u0026 message) = 0;\n};\n\nclass ConsoleLogger : public Logger {\npublic:\n    void log(const std::string\u0026 message) override {\n        std::cout \u003c\u003c message \u003c\u003c std::endl;\n    }\n};\n\nclass FileLogger : public Logger {\npublic:\n    void log(const std::string\u0026 message) override {\n        std::ofstream file(\"log.txt\");\n        file \u003c\u003c message \u003c\u003c std::endl;\n    }\n};\n```\n\nIn this example, the Logger class defines the interface for logging messages, while the ConsoleLogger and FileLogger classes implement that interface for specific output destinations. If a new output destination is needed (e.g. a network log), a new class can be created without modifying the existing code.\n\n## Liskov Substitution Principle\n\nThe LSP states that subtypes should be substitutable for their base types, without affecting the correctness of the program. This means that derived classes should not break the behavior of the base class. For example:\n\n```cpp\nclass Animal {\npublic:\n    virtual void makeSound() const = 0;\n};\n\nclass Cat : public Animal {\npublic:\n    void makeSound() const override {\n        std::cout \u003c\u003c \"Meow!\" \u003c\u003c std::endl;\n    }\n};\n\nclass Dog : public Animal {\npublic:\n    void makeSound() const override {\n        std::cout \u003c\u003c \"Woof!\" \u003c\u003c std::endl;\n    }\n};\n\nvoid makeAnimalSound(const Animal\u0026 animal) {\n    animal.makeSound();\n}\n\nint main() {\n    Cat cat;\n    Dog dog;\n    makeAnimalSound(cat);\n    makeAnimalSound(dog);\n}\n```\n\nIn this example, the Animal class defines the interface for all animals to make a sound. The Cat and Dog classes implement that interface for specific animals, and can be substituted for Animal without affecting the correctness of the program.\n\n## Interface Segregation Principle\n\nThe ISP states that a client should not be forced to depend on methods it does not use. This means that interfaces should be designed to be as small as possible, with only the methods needed by the client. For example:\n\n```cpp\nclass Printer {\npublic:\n    virtual void print() = 0;\n};\n\nclass Scanner {\npublic:\n    virtual void scan() = 0;\n};\n\nclass Copier : public Printer, public Scanner {\npublic:\n    void print() override { /* ... */ }\n    void scan() override { /* ... */ }\n};\n```\n\nIn this example, the Printer and Scanner classes define separate interfaces for printing and scanning, respectively. The Copier class implements both interfaces, and can be used wherever a Printer or Scanner is required.\n\n## Dependency Inversion Principle\n\nThe DIP states that high-level modules should not depend on low-level modules, but both should depend on abstractions. This means that dependencies should be abstracted and injected, rather than hardcoded in the code. For example:\n\n```cpp\nclass Database {\npublic:\n    virtual void save(const std::string\u0026 data) = 0;\n};\n\nclass FileDatabase : public Database {\npublic:\n    void save(const std::string\u0026 data) override {\n        std::ofstream file(\"data.txt\");\n        file \u003c\u003c data \u003c\u003c std::endl;\n    }\n};\n\nclass NetworkDatabase : public Database {\npublic:\n    void save(const std::string\u0026 data) override {\n    // send data over the network\n}\n};\n\nclass DataManager {\npublic:\n    DataManager(Database\u0026 database) : database*(database) {}\n    void saveData(const std::string\u0026 data) {\n        database*.save(data);\n    }\nprivate:\n    Database\u0026 database\\_;\n};\n\nint main() {\n    FileDatabase fileDatabase;\n    DataManager dataManager(fileDatabase);\n    dataManager.saveData(\"data\");\n}\n```\n\nIn this example, the Database class defines the interface for saving data, while the FileDatabase and NetworkDatabase classes implement that interface for specific storage types. The DataManager class depends on the Database abstraction, which is injected into the constructor. This allows different storage types to be used without changing the DataManager code.\n\n## Package Level Software Design principles\n\nHere are some of the most important package level design principles:\n\n-   Cohesion: Packages should contain related functionality and have a clear and well-defined purpose.\n\n-   Coupling: Packages should have low coupling, meaning that they should be loosely connected to other packages. This reduces the impact of changes in one package on other packages.\n\n-   Encapsulation: Packages should encapsulate implementation details, meaning that the package's internal structure and behavior should be hidden from other packages.\n\n-   Abstraction: Packages should be designed to be abstract and generic, which makes them easier to reuse in other projects.\n\n-   Modularity: Packages should be modular, meaning that they can be easily added, removed, or replaced without affecting the rest of the system.\n\n-   Stability: Packages should be stable, meaning that their interfaces and behavior should remain relatively unchanged over time.\n\nBy following these principles, software developers can create packages that are easy to understand, maintain, and extend. This, in turn, leads to better software quality, higher productivity, and lower maintenance costs.\n\n## Release Reuse Equibalency Principle\n\nThe Release Reuse Equivalency Principle (REP) is a software design principle that states that the cost of creating and maintaining reusable software components should be roughly equivalent to the cost of creating and maintaining the same functionality from scratch for a specific application.\n\nThe principle is based on the idea that the time and effort required to design, develop, test, document, and maintain a reusable software component can be significant, and may not be worth the investment if the component is not likely to be reused in multiple applications.\n\nAccording to the REP, the decision to create a reusable software component should be based on the expected frequency and scope of reuse, as well as the expected cost of developing and maintaining the component. If the expected reuse is low and the cost of creating a reusable component is high, it may be more cost-effective to simply implement the functionality from scratch for each application.\n\nIn practice, the REP can help software designers make informed decisions about whether to create reusable software components, and can help ensure that the costs and benefits of reusability are carefully considered in the design process.\n\n## Common Clousure Principle\n\nThe Common Closure Principle (CCP) is a software design principle that states that classes and modules should be designed and grouped together based on the types of changes that are likely to affect them.\n\nAccording to CCP, classes and modules that are likely to be changed together should be grouped together, while classes and modules that are likely to be changed independently should be separated. The principle is based on the idea that changes to a software system should be localized and limited in scope, and that this can be achieved by designing modules that are cohesive and loosely coupled.\n\nIn practice, the CCP can be applied in several ways, including:\n\nGrouping together classes that are part of the same feature or functionality, and that are likely to be modified together in response to changes in the requirements or use cases.\nSeparating classes that have different responsibilities or concerns, and that are likely to be modified independently of each other.\nDesigning modules with clear and well-defined boundaries, and ensuring that changes within a module do not affect other modules in the system.\nBy applying the CCP, software designers can create software systems that are easier to maintain, modify, and extend over time, and that are less likely to be affected by unintended consequences of changes to the system.\n\n## Common Reuse Principle\n\nThe Common Reuse Principle (CRP) is a software design principle that states that classes and modules should be designed and grouped together based on the types of functionality that they provide, rather than the types of changes that are likely to affect them.\n\nAccording to the CRP, classes and modules that provide similar or related functionality should be grouped together and designed for reuse, so that they can be shared and reused across multiple applications. The principle is based on the idea that creating reusable software components can save time and effort in the long run, by reducing duplication and ensuring that code is written once and used multiple times.\n\nIn practice, the CRP can be applied in several ways, including:\n\nCreating reusable libraries or frameworks that provide a set of common functionality that can be used across multiple applications.\nDesigning classes and modules with a clear and well-defined purpose, and ensuring that they can be easily reused in different contexts.\nEncouraging the use of design patterns and other best practices for creating reusable software components.\nBy applying the CRP, software designers can create software systems that are easier to maintain, modify, and extend over time, and that can provide a higher level of quality and consistency across different applications. However, it is important to balance the benefits of reusability with the costs and effort required to create and maintain reusable software components.\n\n## Acyclic Dependencies Principle\n\nThe Acyclic Dependencies Principle (ADP) is a software design principle that states that dependencies between packages or modules in a software system should be acyclic. In other words, there should be no circular dependencies between packages or modules.\n\nCircular dependencies can lead to several problems, including difficulty in understanding and modifying the system, increased risk of introducing bugs or unintended side effects, and reduced ability to reuse or test components in isolation.\n\nTo apply the ADP, software designers should strive to:\n\nIdentify and eliminate circular dependencies between packages or modules in the system.\nDesign packages or modules with well-defined and narrow responsibilities, so that they can be easily understood, reused, and tested in isolation.\nUse techniques such as dependency injection or inversion of control to minimize the impact of dependencies between modules.\nBy applying the ADP, software designers can create software systems that are more modular, flexible, and maintainable over time, and that can be easily extended or adapted to meet changing requirements or use cases.\n\n## Stable Dependcies Principle\n\nThe Stable Dependencies Principle (SDP) is a software design principle that states that packages or modules should depend on other packages or modules that are more stable than they are. Stability is measured by the degree of change that a package or module undergoes over time. A more stable module is one that is less likely to change, while a less stable module is one that is more likely to change.\n\nAccording to the SDP, packages or modules that are more stable should be designed to have fewer dependencies, while packages or modules that are less stable should be designed to have more dependencies. This helps to ensure that changes to less stable packages or modules are less likely to affect more stable packages or modules, and that the system as a whole is more resilient to change.\n\nIn practice, the SDP can be applied in several ways, including:\n\nDesigning packages or modules with well-defined and narrow responsibilities, so that they are less likely to change over time.\nIdentifying and tracking changes to packages or modules over time, and using this information to inform design decisions and dependencies between modules.\nEncouraging the use of design patterns and other best practices for reducing coupling and increasing cohesion between modules.\nBy applying the SDP, software designers can create software systems that are more resilient to change, and that can be easily maintained and extended over time.\n\n# Software Design Patterns\n\nDesign patterns are general, reusable solutions to common problems in software design. They provide proven approaches to creating flexible, maintainable, and reusable software. Design patterns are organized into categories, including creational patterns, structural patterns, and behavioral patterns. By following design patterns, developers can save time and effort, improve communication and collaboration, and avoid common mistakes in software design.\n\n## Creational Design Patterns\n\nCreational design patterns are concerned with object creation mechanisms, trying to create objects in a manner suitable to the situation. They aim to abstract the object instantiation process while making the system more flexible and decoupled from the creation process.\n\nThe primary goal of Creational patterns is to make the system independent of how its objects are created, composed, and represented. They provide mechanisms to create objects in a manner suitable for a specific situation while ensuring that the creation is abstracted and decoupled from the system.\n\n### Singleton Pattern\n\nThis pattern ensures that only one instance of a class is created and provides a global point of access to it. It is often used in situations where it is necessary to limit the number of instances of a class.\n\n```cpp\nclass Singleton {\nprivate:\n    static Singleton* instance;\n    Singleton() {}\npublic:\n    static Singleton* getInstance() {\n        if (instance == nullptr) {\n            instance = new Singleton();\n        }\n        return instance;\n    }\n};\n\nSingleton* Singleton::instance = nullptr;\n\nint main() {\n    Singleton* s1 = Singleton::getInstance();\n    Singleton* s2 = Singleton::getInstance();\n    assert(s1 == s2);\n}\n```\n\n### Factory Pattern\n\nThis pattern provides an interface for creating objects, but allows subclasses to decide which class to instantiate. It is often used when there are multiple classes that can be instantiated from a single interface.\n\n```cpp\nclass Animal {\npublic:\n    virtual void makeSound() = 0;\n};\n\nclass Dog : public Animal {\npublic:\n    void makeSound() override {\n        std::cout \u003c\u003c \"Woof!\\n\";\n    }\n};\n\nclass Cat : public Animal {\npublic:\n    void makeSound() override {\n        std::cout \u003c\u003c \"Meow!\\n\";\n    }\n};\n\nclass AnimalFactory {\npublic:\n    virtual Animal* createAnimal() = 0;\n};\n\nclass DogFactory : public AnimalFactory {\npublic:\n    Animal* createAnimal() override {\n        return new Dog();\n    }\n};\n\nclass CatFactory : public AnimalFactory {\npublic:\n    Animal* createAnimal() override {\n        return new Cat();\n    }\n};\n\nint main() {\n    AnimalFactory* dogFactory = new DogFactory();\n    Animal* dog = dogFactory-\u003ecreateAnimal();\n    dog-\u003emakeSound();\n\n    AnimalFactory* catFactory = new CatFactory();\n    Animal* cat = catFactory-\u003ecreateAnimal();\n    cat-\u003emakeSound();\n}\n\n```\n\n### Abstract Factory Pattern\n\nThis pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. It is often used when there are multiple families of related objects that need to be created.\n\n```cpp\n// Abstract Product A interface\nclass Character {\npublic:\n    virtual void attack() = 0;\n};\n\n// Concrete Product A1\nclass Warrior : public Character {\npublic:\n    void attack() {\n        std::cout \u003c\u003c \"Warrior attacks with a sword\" \u003c\u003c std::endl;\n    }\n};\n\n// Concrete Product A2\nclass Mage : public Character {\npublic:\n    void attack() {\n        std::cout \u003c\u003c \"Mage attacks with a spell\" \u003c\u003c std::endl;\n    }\n};\n\n// Abstract Product B interface\nclass Weapon {\npublic:\n    virtual void use() = 0;\n};\n\n// Concrete Product B1\nclass Sword : public Weapon {\npublic:\n    void use() {\n        std::cout \u003c\u003c \"Warrior uses a sword\" \u003c\u003c std::endl;\n    }\n};\n\n// Concrete Product B2\nclass Spell : public Weapon {\npublic:\n    void use() {\n        std::cout \u003c\u003c \"Mage uses a spell\" \u003c\u003c std::endl;\n    }\n};\n\n// Abstract Factory interface\nclass AbstractFactory {\npublic:\n    virtual Character* createCharacter() = 0;\n    virtual Weapon* createWeapon() = 0;\n};\n\n// Concrete Factory 1\nclass WarriorFactory : public AbstractFactory {\npublic:\n    Character* createCharacter() {\n        return new Warrior();\n    }\n\n    Weapon* createWeapon() {\n        return new Sword();\n    }\n};\n\n// Concrete Factory 2\nclass MageFactory : public AbstractFactory {\npublic:\n    Character* createCharacter() {\n        return new Mage();\n    }\n\n    Weapon* createWeapon() {\n        return new Spell();\n    }\n};\n\nint main() {\n    AbstractFactory* factory;\n    Character* character;\n    Weapon* weapon;\n\n    // Create a Warrior and Sword using the WarriorFactory\n    factory = new WarriorFactory();\n    character = factory-\u003ecreateCharacter();\n    weapon = factory-\u003ecreateWeapon();\n    character-\u003eattack();\n    weapon-\u003euse();\n\n    // Create a Mage and Spell using the MageFactory\n    factory = new MageFactory();\n    character = factory-\u003ecreateCharacter();\n    weapon = factory-\u003ecreateWeapon();\n    character-\u003eattack();\n    weapon-\u003euse();\n\n    return 0;\n}\n```\n\n### Builder Pattern\n\nThe Builder pattern is a creational design pattern that separates the construction of a complex object from its representation. It allows you to create different variations of the object by using the same construction process. Here's an example of how you can implement the Builder pattern in C++:\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\n// Product class\nclass Burger {\npublic:\n    void setBun(const std::string\u0026 bun) {\n        m_bun = bun;\n    }\n\n    void setPatty(const std::string\u0026 patty) {\n        m_patty = patty;\n    }\n\n    void addTopping(const std::string\u0026 topping) {\n        m_toppings += \" \" + topping;\n    }\n\n    void describe() const {\n        std::cout \u003c\u003c \"Burger with \" \u003c\u003c m_bun \u003c\u003c \" bun, \" \u003c\u003c m_patty \u003c\u003c \" patty, and the following toppings:\" \u003c\u003c m_toppings \u003c\u003c std::endl;\n    }\n\nprivate:\n    std::string m_bun;\n    std::string m_patty;\n    std::string m_toppings;\n};\n\n// Abstract Builder interface\nclass BurgerBuilder {\npublic:\n    virtual ~BurgerBuilder() {}\n\n    virtual void buildBun() = 0;\n    virtual void buildPatty() = 0;\n    virtual void buildToppings() = 0;\n    virtual Burger* getBurger() = 0;\n};\n\n// Concrete Builder 1\nclass CheeseburgerBuilder : public BurgerBuilder {\npublic:\n    void buildBun() {\n        m_burger-\u003esetBun(\"sesame seed\");\n    }\n\n    void buildPatty() {\n        m_burger-\u003esetPatty(\"beef\");\n    }\n\n    void buildToppings() {\n        m_burger-\u003eaddTopping(\"cheese\");\n        m_burger-\u003eaddTopping(\"lettuce\");\n        m_burger-\u003eaddTopping(\"tomato\");\n    }\n\n    Burger* getBurger() {\n        return m_burger;\n    }\n\nprivate:\n    Burger* m_burger = new Burger();\n};\n\n// Concrete Builder 2\nclass VeggieBurgerBuilder : public BurgerBuilder {\npublic:\n    void buildBun() {\n        m_burger-\u003esetBun(\"whole wheat\");\n    }\n\n    void buildPatty() {\n        m_burger-\u003esetPatty(\"veggie\");\n    }\n\n    void buildToppings() {\n        m_burger-\u003eaddTopping(\"lettuce\");\n        m_burger-\u003eaddTopping(\"tomato\");\n        m_burger-\u003eaddTopping(\"avocado\");\n    }\n\n    Burger* getBurger() {\n        return m_burger;\n    }\n\nprivate:\n    Burger* m_burger = new Burger();\n};\n\n// Director class\nclass BurgerDirector {\npublic:\n    BurgerDirector(BurgerBuilder* builder)\n        : m_builder(builder) {\n    }\n\n    void makeBurger() {\n        m_builder-\u003ebuildBun();\n        m_builder-\u003ebuildPatty();\n        m_builder-\u003ebuildToppings();\n    }\n\n    Burger* getBurger() {\n        return m_builder-\u003egetBurger();\n    }\n\nprivate:\n    BurgerBuilder* m_builder;\n};\n\nint main() {\n    BurgerBuilder* builder = new CheeseburgerBuilder();\n    BurgerDirector director(builder);\n    director.makeBurger();\n    Burger* burger = director.getBurger();\n    burger-\u003edescribe();\n\n    builder = new VeggieBurgerBuilder();\n    director = BurgerDirector(builder);\n    director.makeBurger();\n    burger = director.getBurger();\n    burger-\u003edescribe();\n\n    return 0;\n}\n```\n\n### Prototype Pattern\n\nThe Prototype pattern is a creational pattern that allows creating new objects by copying existing objects, rather than creating them from scratch. In this pattern, a client creates a prototype object, and then creates new objects by cloning the prototype.\n\n```cpp\nclass Maze {\npublic:\n    virtual Maze* Clone() const = 0;\n    virtual void Print() const = 0;\n};\nclass SmallMaze : public Maze {\npublic:\n    Maze* Clone() const {\n        return new SmallMaze(*this);\n    }\n\n    void Print() const {\n        std::cout \u003c\u003c \"Small maze\" \u003c\u003c std::endl;\n        // ... implementation for printing small maze ...\n    }\n};\nclass LargeMaze : public Maze {\npublic:\n    Maze* Clone() const {\n        return new LargeMaze(*this);\n    }\n\n    void Print() const {\n        std::cout \u003c\u003c \"Large maze\" \u003c\u003c std::endl;\n        // ... implementation for printing large maze ...\n    }\n};\nint main() {\n    Maze* smallMaze = new SmallMaze();\n    Maze* largeMaze = new LargeMaze();\n\n    Maze* clonedSmallMaze = smallMaze-\u003eClone();\n    Maze* clonedLargeMaze = largeMaze-\u003eClone();\n\n    smallMaze-\u003ePrint();\n    clonedSmallMaze-\u003ePrint();\n\n    largeMaze-\u003ePrint();\n    clonedLargeMaze-\u003ePrint();\n\n    delete smallMaze;\n    delete largeMaze;\n    delete clonedSmallMaze;\n    delete clonedLargeMaze;\n\n    return 0;\n}\n```\n\n### Object Pool Pattern\n\nThe Object Pool pattern is a creational pattern that uses a pool of reusable objects instead of creating new objects every time they are needed. This can help reduce the overhead of creating new objects and improve performance.\n\nHere's an example implementation of the Object Pool pattern in C++:\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\n\n// The object to be reused (database connection)\nclass DatabaseConnection {\npublic:\n    DatabaseConnection(const std::string\u0026 connectionString) :\n        m_connectionString(connectionString),\n        m_isOpen(false) {}\n\n    bool Open() {\n        if (!m_isOpen) {\n            std::cout \u003c\u003c \"Opening database connection: \" \u003c\u003c m_connectionString \u003c\u003c std::endl;\n            m_isOpen = true;\n        }\n        return m_isOpen;\n    }\n\n    bool Close() {\n        if (m_isOpen) {\n            std::cout \u003c\u003c \"Closing database connection: \" \u003c\u003c m_connectionString \u003c\u003c std::endl;\n            m_isOpen = false;\n        }\n        return !m_isOpen;\n    }\n\nprivate:\n    std::string m_connectionString;\n    bool m_isOpen;\n};\n\n// The object pool\nclass ConnectionPool {\nprivate:\n    std::vector\u003cDatabaseConnection*\u003e m_connections;\n    int m_maxSize;\n    std::string m_connectionString;\n\npublic:\n    ConnectionPool(const std::string\u0026 connectionString, int maxSize) :\n        m_maxSize(maxSize),\n        m_connectionString(connectionString) {\n        // Populate the object pool with initial connections\n        for (int i = 0; i \u003c maxSize; i++) {\n            m_connections.push_back(new DatabaseConnection(connectionString));\n        }\n    }\n\n    DatabaseConnection* AcquireConnection() {\n        DatabaseConnection* connection = nullptr;\n\n        // Check if there is an available connection in the pool\n        if (m_connections.size() \u003e 0) {\n            // Acquire a connection from the pool\n            connection = m_connections.back();\n            m_connections.pop_back();\n        }\n        else {\n            // Create a new connection if the pool is empty\n            connection = new DatabaseConnection(m_connectionString);\n        }\n\n        return connection;\n    }\n\n    void ReleaseConnection(DatabaseConnection* connection) {\n        // Check if the pool is already full\n        if (m_connections.size() \u003e= m_maxSize) {\n            // If the pool is full, delete the connection\n            delete connection;\n        }\n        else {\n            // Release the connection back to the pool\n            connection-\u003eClose();\n            m_connections.push_back(connection);\n        }\n    }\n};\n\nint main() {\n    // Create a connection pool with a maximum of 3 connections\n    ConnectionPool pool(\"localhost:3306\", 3);\n\n    // Acquire and release 5 connections\n    for (int i = 0; i \u003c 5; i++) {\n        DatabaseConnection* connection = pool.AcquireConnection();\n        connection-\u003eOpen();\n        // Do some database work...\n        pool.ReleaseConnection(connection);\n    }\n\n    return 0;\n}\n```\n\n## Structural Design Patterns\n\nStructural design patterns are concerned with how objects and classes are composed to form larger structures or systems. These patterns provide ways to simplify the relationships between objects and classes, making it easier to modify, extend, and reuse code.\n\n### Adapter Pattern\n\nThe Adapter pattern is a structural design pattern that allows objects with incompatible interfaces to collaborate by creating an adapter object that acts as a bridge between them. It is used when an existing class doesn't meet the requirements of a new system, and you want to reuse the class without modifying its code.\n\nIn the Adapter pattern, the adapter acts as an intermediary between the client and the adaptee. The client communicates with the adapter using a target interface, which the adapter then translates into the interface of the adaptee.\n\nHere is an example in C++:\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\n// Target interface\nclass IVideoPlayer {\npublic:\n    virtual void playAVI(std::string filename) = 0;\n};\n\n// Adaptee class\nclass MP4Player {\npublic:\n    void playMP4(std::string filename) {\n        std::cout \u003c\u003c \"Playing MP4 file: \" \u003c\u003c filename \u003c\u003c std::endl;\n    }\n};\n\n// Adapter class\nclass MP4PlayerAdapter : public IVideoPlayer {\nprivate:\n    MP4Player* mp4Player;\n\npublic:\n    MP4PlayerAdapter(MP4Player* player) {\n        mp4Player = player;\n    }\n\n    void playAVI(std::string filename) override {\n        // Convert the AVI filename to MP4 filename\n        std::string mp4Filename = filename.substr(0, filename.find_last_of(\".\")) + \".mp4\";\n        mp4Player-\u003eplayMP4(mp4Filename);\n    }\n};\n\n// Client code\nvoid playVideo(IVideoPlayer* player, std::string filename) {\n    player-\u003eplayAVI(filename);\n}\n\nint main() {\n    // Create an instance of the adaptee class\n    MP4Player* mp4Player = new MP4Player();\n\n    // Create an adapter object that wraps the adaptee\n    IVideoPlayer* adapter = new MP4PlayerAdapter(mp4Player);\n\n    // Play the video using the adapter object\n    playVideo(adapter, \"example.avi\");\n\n    delete mp4Player;\n    delete adapter;\n\n    return 0;\n}\n```\n\n### Bridge Pattern\n\nThe Bridge pattern is a design pattern that allows you to separate the implementation of a feature from its abstraction, so that they can vary independently.\n\n```cpp\n#include \u003ciostream\u003e\nusing namespace std;\n\n// Implementor interface\nclass TV {\npublic:\n    virtual void on() = 0;\n    virtual void off() = 0;\n    virtual void setChannel(int channel) = 0;\n    virtual void setVolume(int volume) = 0;\n};\n\n// Concrete Implementor 1\nclass SonyTV : public TV {\npublic:\n    void on() {\n        cout \u003c\u003c \"Sony TV is on\" \u003c\u003c endl;\n    }\n    void off() {\n        cout \u003c\u003c \"Sony TV is off\" \u003c\u003c endl;\n    }\n    void setChannel(int channel) {\n        cout \u003c\u003c \"Sony TV channel is set to \" \u003c\u003c channel \u003c\u003c endl;\n    }\n    void setVolume(int volume) {\n        cout \u003c\u003c \"Sony TV volume is set to \" \u003c\u003c volume \u003c\u003c endl;\n    }\n};\n\n// Concrete Implementor 2\nclass SamsungTV : public TV {\npublic:\n    void on() {\n        cout \u003c\u003c \"Samsung TV is on\" \u003c\u003c endl;\n    }\n    void off() {\n        cout \u003c\u003c \"Samsung TV is off\" \u003c\u003c endl;\n    }\n    void setChannel(int channel) {\n        cout \u003c\u003c \"Samsung TV channel is set to \" \u003c\u003c channel \u003c\u003c endl;\n    }\n    void setVolume(int volume) {\n        cout \u003c\u003c \"Samsung TV volume is set to \" \u003c\u003c volume \u003c\u003c endl;\n    }\n};\n\n// Abstraction interface\nclass RemoteControl {\npublic:\n    virtual void turnOn() = 0;\n    virtual void turnOff() = 0;\n    virtual void setChannel(int channel) = 0;\n    virtual void setVolume(int volume) = 0;\n    virtual void show() = 0;\n\nprotected:\n    TV* tv;\n};\n\n// Refined Abstraction 1\nclass BasicRemoteControl : public RemoteControl {\npublic:\n    BasicRemoteControl(TV* tv) {\n        this-\u003etv = tv;\n    }\n    void turnOn() {\n        tv-\u003eon();\n    }\n    void turnOff() {\n        tv-\u003eoff();\n    }\n    void setChannel(int channel) {\n        tv-\u003esetChannel(channel);\n    }\n    void setVolume(int volume) {\n        tv-\u003esetVolume(volume);\n    }\n    void show() {\n        cout \u003c\u003c \"Basic Remote Control:\" \u003c\u003c endl;\n    }\n};\n\n// Refined Abstraction 2\nclass AdvancedRemoteControl : public RemoteControl {\npublic:\n    AdvancedRemoteControl(TV* tv) {\n        this-\u003etv = tv;\n    }\n    void turnOn() {\n        tv-\u003eon();\n    }\n    void turnOff() {\n        tv-\u003eoff();\n    }\n    void setChannel(int channel) {\n        tv-\u003esetChannel(channel);\n    }\n    void setVolume(int volume) {\n        tv-\u003esetVolume(volume);\n    }\n    void mute() {\n        tv-\u003esetVolume(0);\n        cout \u003c\u003c \"TV is muted\" \u003c\u003c endl;\n    }\n    void show() {\n        cout \u003c\u003c \"Advanced Remote Control:\" \u003c\u003c endl;\n    }\n};\n\n// Client code\nint main() {\n    TV* sony = new SonyTV();\n    TV* samsung = new SamsungTV();\n\n    RemoteControl* basicRemote = new BasicRemoteControl(sony);\n    RemoteControl* advancedRemote = new AdvancedRemoteControl(samsung);\n\n    basicRemote-\u003eshow();\n    basicRemote-\u003eturnOn();\n    basicRemote-\u003esetChannel(3);\n    basicRemote-\u003esetVolume(10);\n    basicRemote-\u003eturnOff();\n\n    advancedRemote-\u003eshow();\n    advancedRemote-\u003eturnOn();\n    advancedRemote-\u003esetChannel(7);\n    advancedRemote-\u003esetVolume(20);\n    advancedRemote-\u003emute();\n    advancedRemote-\u003eturnOff();\n\n}\n```\n\n### Composite Pattern\n\nThe Composite pattern is a structural design pattern that allows you to treat a group of objects in the same way as a single object. It composes objects into tree structures to represent part-whole hierarchies.\n\nIn the Composite pattern, there are two types of objects: the composite object and the leaf object. The composite object represents a group of objects and contains a list of its child objects, while the leaf object represents an individual object in the group.\n\nHere's an example implementation of the Composite pattern in C++:\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\n\nclass FileSystemNode {\npublic:\n    virtual std::string getName() = 0;\n    virtual void ls() = 0;\n    virtual void addNode(FileSystemNode* node) {}\n    virtual void removeNode(FileSystemNode* node) {}\n};\n\nclass File : public FileSystemNode {\npublic:\n    File(std::string name) : name(name) {}\n\n    std::string getName() {\n        return name;\n    }\n\n    void ls() {\n        std::cout \u003c\u003c getName() \u003c\u003c std::endl;\n    }\n\nprivate:\n    std::string name;\n};\n\nclass Directory : public FileSystemNode {\npublic:\n    Directory(std::string name) : name(name) {}\n\n    std::string getName() {\n        return name;\n    }\n\n    void ls() {\n        std::cout \u003c\u003c getName() \u003c\u003c \"/\" \u003c\u003c std::endl;\n        for (FileSystemNode* node : nodes) {\n            std::cout \u003c\u003c \"  \";\n            node-\u003els();\n        }\n    }\n\n    void addNode(FileSystemNode* node) {\n        nodes.push_back(node);\n    }\n\n    void removeNode(FileSystemNode* node) {\n        nodes.erase(std::remove(nodes.begin(), nodes.end(), node), nodes.end());\n    }\n\nprivate:\n    std::string name;\n    std::vector\u003cFileSystemNode*\u003e nodes;\n};\n\nint main() {\n    FileSystemNode* file1 = new File(\"file1.txt\");\n    FileSystemNode* file2 = new File(\"file2.txt\");\n\n    FileSystemNode* dir1 = new Directory(\"dir1\");\n    dir1-\u003eaddNode(file1);\n\n    FileSystemNode* dir2 = new Directory(\"dir2\");\n    dir2-\u003eaddNode(file2);\n\n    FileSystemNode* root = new Directory(\"root\");\n    root-\u003eaddNode(dir1);\n    root-\u003eaddNode(dir2);\n\n    root-\u003els();\n\n    return 0;\n}\n```\n\n### Decorator Pattern\n\nThe Decorator pattern is used to dynamically add functionality to an object by wrapping it in a decorator class. The decorator class has the same interface as the original object, and adds its own behavior before or after calling the original object's methods.\n\n```cpp\nclass Pizza {\npublic:\n    virtual ~Pizza() {}\n    virtual int get_cost() = 0;\n};\n\nclass Margherita : public Pizza {\npublic:\n    int get_cost() override {\n        return 10;\n    }\n};\n\nclass Pepperoni : public Pizza {\npublic:\n    int get_cost() override {\n        return 12;\n    }\n};\n\nclass PizzaDecorator : public Pizza {\npublic:\n    PizzaDecorator(Pizza* pizza) : pizza_(pizza) {}\nprotected:\n    Pizza* pizza_;\n};\n\nclass Cheese : public PizzaDecorator {\npublic:\n    Cheese(Pizza* pizza) : PizzaDecorator(pizza) {}\n    int get_cost() override {\n        return pizza_-\u003eget_cost() + 2;\n    }\n};\n\nclass Ham : public PizzaDecorator {\npublic:\n    Ham(Pizza* pizza) : PizzaDecorator(pizza) {}\n    int get_cost() override {\n        return pizza_-\u003eget_cost() + 3;\n    }\n};\n\nint main(){\n    Pizza* margherita = new Margherita();\n    Pizza* margherita_with_cheese = new Cheese(margherita);\n    Pizza* pepperoni_with_cheese_and_ham = new Ham(new Cheese(new Pepperoni()));\n\n    std::cout \u003c\u003c margherita_with_cheese-\u003eget_cost() \u003c\u003c std::endl;  // output: 12\n    std::cout \u003c\u003c pepperoni_with_cheese_and_ham-\u003eget_cost() \u003c\u003c std::endl;  // output: 17\n\n    return 0;\n}\n```\n\n### Facade Pattern\n\nThe Facade pattern is a structural design pattern that provides a simplified interface to a complex system or group of subsystems. It provides a high-level interface that makes the subsystem easier to use and reduces the complexity of the code.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\nclass EmailService {\npublic:\n    void sendEmail(std::string email, std::string message) {\n        std::cout \u003c\u003c \"Sending email to \" \u003c\u003c email \u003c\u003c \": \" \u003c\u003c message \u003c\u003c std::endl;\n    }\n};\n\nclass SMSService {\npublic:\n    void sendSMS(std::string phone, std::string message) {\n        std::cout \u003c\u003c \"Sending SMS to \" \u003c\u003c phone \u003c\u003c \": \" \u003c\u003c message \u003c\u003c std::endl;\n    }\n};\n\nclass PushNotificationService {\npublic:\n    void sendPushNotification(std::string deviceToken, std::string message) {\n        std::cout \u003c\u003c \"Sending push notification to \" \u003c\u003c deviceToken \u003c\u003c \": \" \u003c\u003c message \u003c\u003c std::endl;\n    }\n};\n\nclass NotificationSystem {\nprivate:\n    EmailService emailService;\n    SMSService smsService;\n    PushNotificationService pushNotificationService;\npublic:\n    void sendNotification(std::string email, std::string phone, std::string deviceToken, std::string message) {\n        emailService.sendEmail(email, message);\n        smsService.sendSMS(phone, message);\n        pushNotificationService.sendPushNotification(deviceToken, message);\n    }\n};\n\nint main() {\n    NotificationSystem notificationSystem;\n    notificationSystem.sendNotification(\"johndoe@example.com\", \"+1234567890\", \"abcd1234\", \"Hello, world!\");\n    return 0;\n}\n```\n\n### Flyweight Pattern\n\nThe Flyweight design pattern is a structural pattern that helps to minimize the memory usage of an application by sharing objects that have similar data.\n\n```cpp\n #include \u003ciostream\u003e\n#include \u003cstring\u003e\n#include \u003cunordered_map\u003e\n\nusing namespace std;\n\n// The Flyweight class\nclass Character {\npublic:\n    virtual void render() = 0;\n};\n\n// The ConcreteFlyweight class\nclass Player : public Character {\npublic:\n    Player(string name, int health, int attackPower, string image) {\n        this-\u003ename = name;\n        this-\u003ehealth = health;\n        this-\u003eattackPower = attackPower;\n        this-\u003eimage = image;\n    }\n\n    void render() {\n        cout \u003c\u003c \"Name: \" \u003c\u003c name \u003c\u003c endl;\n        cout \u003c\u003c \"Health: \" \u003c\u003c health \u003c\u003c endl;\n        cout \u003c\u003c \"Attack Power: \" \u003c\u003c attackPower \u003c\u003c endl;\n        cout \u003c\u003c \"Image: \" \u003c\u003c image \u003c\u003c endl;\n        cout \u003c\u003c endl;\n    }\n\nprivate:\n    string name;\n    int health;\n    int attackPower;\n    string image;\n};\n\n// The FlyweightFactory class\nclass CharacterFactory {\npublic:\n    Character* getCharacter(string name) {\n        if (characters.find(name) == characters.end()) {\n            // If character does not exist, create a new one and add it to the pool\n            cout \u003c\u003c \"Creating new character: \" \u003c\u003c name \u003c\u003c endl;\n            characters[name] = new Player(name, 100, 10, \"player.png\");\n        }\n        else {\n            // If character exists, return the existing one from the pool\n            cout \u003c\u003c \"Returning existing character: \" \u003c\u003c name \u003c\u003c endl;\n        }\n        return characters[name];\n    }\n\n    ~CharacterFactory() {\n        for (auto it : characters) {\n            delete it.second;\n        }\n        characters.clear();\n    }\n\nprivate:\n    unordered_map\u003cstring, Character*\u003e characters;\n};\n\nint main() {\n    CharacterFactory* factory = new CharacterFactory();\n\n    // Get two instances of the same character\n    Character* player1 = factory-\u003egetCharacter(\"Player1\");\n    Character* player2 = factory-\u003egetCharacter(\"Player1\");\n\n    // Get a new instance of a different character\n    Character* player3 = factory-\u003egetCharacter(\"Player2\");\n\n    // Render the characters\n    player1-\u003erender();\n    player2-\u003erender();\n    player3-\u003erender();\n\n    // Clean up memory\n    delete factory;\n\n    return 0;\n}\n```\n\n### Proxy Pattern\n\nThe Proxy pattern is a structural pattern that provides a surrogate or placeholder object to control access to another object. The proxy object acts as an intermediary between the client and the real object, and it can perform additional tasks such as caching, security checks, or resource management.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\nusing namespace std;\n\n// The Subject interface\nclass BankAccount {\npublic:\n    virtual void deposit(int amount) = 0;\n    virtual void withdraw(int amount) = 0;\n    virtual int getBalance() = 0;\n};\n\n// The RealSubject class\nclass RealBankAccount : public BankAccount {\npublic:\n    RealBankAccount(string name, string password) {\n        this-\u003ename = name;\n        this-\u003epassword = password;\n        balance = 0;\n    }\n\n    void deposit(int amount) {\n        balance += amount;\n        cout \u003c\u003c \"Deposit successful. New balance: \" \u003c\u003c balance \u003c\u003c endl;\n    }\n\n    void withdraw(int amount) {\n        if (balance \u003e= amount) {\n            balance -= amount;\n            cout \u003c\u003c \"Withdrawal successful. New balance: \" \u003c\u003c balance \u003c\u003c endl;\n        }\n        else {\n            cout \u003c\u003c \"Insufficient funds.\" \u003c\u003c endl;\n        }\n    }\n\n    int getBalance() {\n        return balance;\n    }\n\nprivate:\n    string name;\n    string password;\n    int balance;\n};\n\n// The Proxy class\nclass BankAccountProxy : public BankAccount {\npublic:\n    BankAccountProxy(string name, string password) {\n        this-\u003ename = name;\n        this-\u003epassword = password;\n        account = nullptr;\n    }\n\n    void deposit(int amount) {\n        if (authorize()) {\n            if (account == nullptr) {\n                account = new RealBankAccount(name, password);\n            }\n            account-\u003edeposit(amount);\n        }\n    }\n\n    void withdraw(int amount) {\n        if (authorize()) {\n            if (account == nullptr) {\n                account = new RealBankAccount(name, password);\n            }\n            account-\u003ewithdraw(amount);\n        }\n    }\n\n    int getBalance() {\n        if (authorize()) {\n            if (account == nullptr) {\n                account = new RealBankAccount(name, password);\n            }\n            return account-\u003egetBalance();\n        }\n        else {\n            return -1;\n        }\n    }\n\nprivate:\n    bool authorize() {\n        // Authenticate the user based on name and password\n        // Check if the user has the required permissions\n        return true;\n    }\n\n    string name;\n    string password;\n    RealBankAccount* account;\n};\n\nint main() {\n    BankAccount* account = new BankAccountProxy(\"Alice\", \"password\");\n\n    account-\u003edeposit(100);\n    account-\u003ewithdraw(50);\n    cout \u003c\u003c \"Balance: \" \u003c\u003c account-\u003egetBalance() \u003c\u003c endl;\n\n    delete account;\n\n    return 0;\n}\n```\n\n## Behavioral Design Patterns\n\nBehavioral design patterns are concerned with algorithms and the assignment of responsibilities between objects. They deal with communication between objects, encapsulating behaviors in objects, and controlling the flow of communication. The key objective of these patterns is to improve communication between objects to make the system more flexible and efficient.\n\n### Chain of Responsiblity Pattern\n\nThe Chain of Responsibility pattern is a behavioral design pattern that allows an object to pass a request through a chain of handlers until it is handled by an appropriate handler. This pattern is useful when multiple objects may be able to handle a request, and the client does not know which object will be able to handle the request.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\nusing namespace std;\n\n// Abstract base class for handlers\nclass OrderHandler {\npublic:\n    virtual void setNext(OrderHandler* nextHandler) = 0;\n    virtual void handleOrder(string vendor, string item, int quantity, string address) = 0;\n};\n\n// Concrete handler that checks if the item is in stock\nclass InventoryHandler : public OrderHandler {\nprivate:\n    OrderHandler* nextHandler;\npublic:\n    void setNext(OrderHandler* nextHandler) {\n        this-\u003enextHandler = nextHandler;\n    }\n\n    void handleOrder(string vendor, string item, int quantity, string address) {\n        // Check if the item is in stock for the given vendor\n        bool isInStock = checkInventory(vendor, item, quantity);\n\n        if (isInStock) {\n            // If the item is in stock, pass the order to the next handler\n            nextHandler-\u003ehandleOrder(vendor, item, quantity, address);\n        } else {\n            cout \u003c\u003c \"Sorry, item is out of stock\" \u003c\u003c endl;\n        }\n    }\n\n    bool checkInventory(string vendor, string item, int quantity) {\n        // Check inventory for the given vendor and item\n        // Return true if there is enough inventory to fulfill the order\n        // Return false if there is not enough inventory to fulfill the order\n        return true;\n    }\n};\n\n// Concrete handler that checks the shipping address\nclass AddressHandler : public OrderHandler {\nprivate:\n    OrderHandler* nextHandler;\npublic:\n    void setNext(OrderHandler* nextHandler) {\n        this-\u003enextHandler = nextHandler;\n    }\n\n    void handleOrder(string vendor, string item, int quantity, string address) {\n        // Check if the shipping address is valid\n        bool isAddressValid = checkAddress(address);\n\n        if (isAddressValid) {\n            // If the address is valid, pass the order to the next handler\n            nextHandler-\u003ehandleOrder(vendor, item, quantity, address);\n        } else {\n            cout \u003c\u003c \"Sorry, invalid shipping address\" \u003c\u003c endl;\n        }\n    }\n\n    bool checkAddress(string address) {\n        // Check if the address is valid\n        // Return true if the address is valid\n        // Return false if the address is invalid\n        return true;\n    }\n};\n\n// Concrete handler that processes the payment\nclass PaymentHandler : public OrderHandler {\nprivate:\n    OrderHandler* nextHandler;\npublic:\n    void setNext(OrderHandler* nextHandler) {\n        this-\u003enextHandler = nextHandler;\n    }\n\n    void handleOrder(string vendor, string item, int quantity, string address) {\n        // Process the payment for the order\n        bool isPaymentProcessed = processPayment();\n\n        if (isPaymentProcessed) {\n            cout \u003c\u003c \"Order for \" \u003c\u003c quantity \u003c\u003c \" \" \u003c\u003c item \u003c\u003c \" from \" \u003c\u003c vendor \u003c\u003c \" to \" \u003c\u003c address \u003c\u003c \" processed successfully\" \u003c\u003c endl;\n        } else {\n            cout \u003c\u003c \"Sorry, payment processing failed\" \u003c\u003c endl;\n        }\n    }\n\n    bool processPayment() {\n        // Process the payment for the order\n        // Return true if the payment is processed successfully\n        // Return false if the payment processing fails\n        return true;\n    }\n};\n\nint main() {\n    // Create the chain of handlers\n    OrderHandler* inventoryHandler = new InventoryHandler();\n    OrderHandler* addressHandler = new AddressHandler();\n    OrderHandler* paymentHandler = new PaymentHandler();\n\n    inventoryHandler-\u003esetNext(addressHandler);\n    addressHandler-\u003esetNext(paymentHandler);\n\n    // Process an order\n    inventoryHandler-\u003ehandleOrder(\"Acme\", \"Widget\", 10, \"123 Main St.\");\n\n    return 0;\n}\n```\n\n### Command Pattern\n\nThe Command pattern is a behavioral design pattern that allows you to encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. In simpler terms, it provides a way to separate the request for an action from the object that actually performs the action.\n\nThe pattern consists of several components: the Command, which is an object that contains information about an action to be performed; the Receiver, which is an object that performs the action; the Invoker, which is an object that receives the Command and asks the Receiver to perform the action; and the Client, which creates the Command and sends it to the Invoker.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\n#include \u003cstring\u003e\nusing namespace std;\n\n// The abstract command class\nclass Command {\npublic:\n    virtual void execute() = 0;\n    virtual void undo() = 0;\n};\n\n// A concrete command for inserting text\nclass InsertCommand : public Command {\nprivate:\n    string text;\n    int position;\n    string previousText;\npublic:\n    InsertCommand(string text, int position) {\n        this-\u003etext = text;\n        this-\u003eposition = position;\n    }\n\n    void execute() {\n        // Save the previous text at the insertion position\n        previousText = document.substr(position, text.length());\n\n        // Insert the new text at the insertion position\n        document.replace(position, text.length(), text);\n    }\n\n    void undo() {\n        // Restore the previous text at the insertion position\n        document.replace(position, text.length(), previousText);\n    }\n};\n\n// A concrete command for deleting text\nclass DeleteCommand : public Command {\nprivate:\n    int position;\n    string deletedText;\npublic:\n    DeleteCommand(int position, int length) {\n        this-\u003eposition = position;\n        deletedText = document.substr(position, length);\n    }\n\n    void execute() {\n        // Delete the text at the deletion position\n        document.erase(position, deletedText.length());\n    }\n\n    void undo() {\n        // Insert the deleted text at the deletion position\n        document.insert(position, deletedText);\n    }\n};\n\n// The invoker\nclass TextEditor {\nprivate:\n    vector\u003cCommand*\u003e undoStack;\npublic:\n    void executeCommand(Command* command) {\n        command-\u003eexecute();\n        undoStack.push_back(command);\n    }\n\n    void undoLastCommand() {\n        if (!undoStack.empty()) {\n            Command* lastCommand = undoStack.back();\n            lastCommand-\u003eundo();\n            undoStack.pop_back();\n        }\n    }\n};\n\n// The client code\nint main() {\n    TextEditor textEditor;\n\n    // Insert some text\n    Command* insertCommand = new InsertCommand(\"Hello, world!\", 0);\n    textEditor.executeCommand(insertCommand);\n\n    // Delete some text\n    Command* deleteCommand = new DeleteCommand(5, 7);\n    textEditor.executeCommand(deleteCommand);\n\n    // Undo the last command\n    textEditor.undoLastCommand();\n\n    // Print the document\n    cout \u003c\u003c document \u003c\u003c endl;\n\n    return 0;\n}\n```\n\n### Observer Pattern\n\nThe observer pattern is used to maintain a one-to-many relationship between objects so that when one object changes state, all its dependents are notified and updated automatically. This pattern is often used to implement event handling, where multiple objects need to react to a change in state.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\nusing namespace std;\n\n// The abstract Observer class\nclass Observer {\npublic:\n    virtual void update(int temperature) = 0;\n};\n\n// The concrete Subject class\nclass TemperatureSensor {\nprivate:\n    vector\u003cObserver*\u003e observers;\n    int temperature;\npublic:\n    void addObserver(Observer* observer) {\n        observers.push_back(observer);\n    }\n\n    void removeObserver(Observer* observer) {\n        for (int i = 0; i \u003c observers.size(); i++) {\n            if (observers[i] == observer) {\n                observers.erase(observers.begin() + i);\n                break;\n            }\n        }\n    }\n\n    void setTemperature(int temperature) {\n        this-\u003etemperature = temperature;\n        notifyObservers();\n    }\n\n    int getTemperature() {\n        return temperature;\n    }\n\n    void notifyObservers() {\n        for (int i = 0; i \u003c observers.size(); i++) {\n            observers[i]-\u003eupdate(temperature);\n        }\n    }\n};\n\n// A concrete Observer that prints the temperature to the console\nclass ConsoleDisplay : public Observer {\npublic:\n    void update(int temperature) {\n        cout \u003c\u003c \"Temperature: \" \u003c\u003c temperature \u003c\u003c endl;\n    }\n};\n\n// A concrete Observer that sends an alert if the temperature goes above a certain threshold\nclass AlertSystem : public Observer {\nprivate:\n    int threshold;\npublic:\n    AlertSystem(int threshold) {\n        this-\u003ethreshold = threshold;\n    }\n\n    void update(int temperature) {\n        if (temperature \u003e threshold) {\n            cout \u003c\u003c \"ALERT: Temperature is above threshold!\" \u003c\u003c endl;\n        }\n    }\n};\n\n// The client code\nint main() {\n    TemperatureSensor temperatureSensor;\n    ConsoleDisplay consoleDisplay;\n    AlertSystem alertSystem(30);\n\n    temperatureSensor.addObserver(\u0026consoleDisplay);\n    temperatureSensor.addObserver(\u0026alertSystem);\n\n    temperatureSensor.setTemperature(25);\n    temperatureSensor.setTemperature(30);\n    temperatureSensor.setTemperature(35);\n\n    temperatureSensor.removeObserver(\u0026alertSystem);\n\n    temperatureSensor.setTemperature(40);\n\n    return 0;\n}\n```\n\n### Iterator Pattern\n\nThe iterator pattern is used to provide a way to access the elements of a collection object in a sequential manner, without exposing its underlying representation. The iterator pattern decouples the algorithm that iterates over the collection from the collection itself, making the algorithm more generic and reusable.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cvector\u003e\nusing namespace std;\n\n// The abstract Iterator class\nclass Iterator {\npublic:\n    virtual bool hasNext() = 0;\n    virtual void* next() = 0;\n};\n\n// The concrete Iterator class for iterating over books\nclass BookIterator : public Iterator {\nprivate:\n    vector\u003cstring\u003e books;\n    int position = 0;\npublic:\n    BookIterator(vector\u003cstring\u003e books) {\n        this-\u003ebooks = books;\n    }\n\n    bool hasNext() {\n        return position \u003c books.size();\n    }\n\n    void* next() {\n        if (hasNext()) {\n            string\u0026 book = books[position++];\n            return \u0026book;\n        }\n        return nullptr;\n    }\n};\n\n// The aggregate class that holds the collection of books\nclass Library {\nprivate:\n    vector\u003cstring\u003e books;\npublic:\n    void addBook(string book) {\n        books.push_back(book);\n    }\n\n    Iterator* createIterator() {\n        return new BookIterator(books);\n    }\n};\n\n// The client code\nint main() {\n    Library library;\n    library.addBook(\"The Great Gatsby\");\n    library.addBook(\"To Kill a Mockingbird\");\n    library.addBook(\"Pride and Prejudice\");\n\n    Iterator* bookIterator = library.createIterator();\n    while (bookIterator-\u003ehasNext()) {\n        string* book = static_cast\u003cstring*\u003e(bookIterator-\u003enext());\n        cout \u003c\u003c *book \u003c\u003c endl;\n    }\n\n    delete bookIterator;\n\n    return 0;\n}\n```\n\n### State Pattern\n\nThe state pattern is a behavioral pattern used in software design to allow an object to alter its behavior when its internal state changes. The pattern involves defining a set of states that an object can be in, and specifying the behavior of the object for each state. The object's behavior is then determined by its current state.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\nusing namespace std;\n\n// The abstract State class\nclass State {\npublic:\n    virtual void addProduct(string product) = 0;\n    virtual void removeProduct(string product) = 0;\n    virtual void checkout() = 0;\n};\n\n// The concrete State class for an empty shopping cart\nclass EmptyCartState : public State {\npublic:\n    void addProduct(string product) {\n        cout \u003c\u003c \"Added product: \" \u003c\u003c product \u003c\u003c endl;\n    }\n\n    void removeProduct(string product) {\n        cout \u003c\u003c \"Cannot remove product, cart is empty\" \u003c\u003c endl;\n    }\n\n    void checkout() {\n        cout \u003c\u003c \"Cannot checkout, cart is empty\" \u003c\u003c endl;\n    }\n};\n\n// The concrete State class for a non-empty shopping cart\nclass NonEmptyCartState : public State {\npublic:\n    void addProduct(string product) {\n        cout \u003c\u003c \"Added product: \" \u003c\u003c product \u003c\u003c endl;\n    }\n\n    void removeProduct(string product) {\n        cout \u003c\u003c \"Removed product: \" \u003c\u003c product \u003c\u003c endl;\n    }\n\n    void checkout() {\n        cout \u003c\u003c \"Checked out\" \u003c\u003c endl;\n    }\n};\n\n// The Context class that manages the current state of the shopping cart\nclass ShoppingCart {\nprivate:\n    State* state;\npublic:\n    ShoppingCart() {\n        state = new EmptyCartState();\n    }\n\n    void setState(State* state) {\n        this-\u003estate = state;\n    }\n\n    void addProduct(string product) {\n        state-\u003eaddProduct(product);\n        setState(new NonEmptyCartState());\n    }\n\n    void removeProduct(string product) {\n        state-\u003eremoveProduct(product);\n        if (state == dynamic_cast\u003cNonEmptyCartState*\u003e(state)) {\n            return;\n        }\n        setState(new EmptyCartState());\n    }\n\n    void checkout() {\n        state-\u003echeckout();\n        setState(new EmptyCartState());\n    }\n};\n\n// The client code\nint main() {\n    ShoppingCart cart;\n\n    cart.addProduct(\"T-shirt\");\n    cart.addProduct(\"Jeans\");\n    cart.checkout();\n\n    cart.addProduct(\"Sneakers\");\n    cart.removeProduct(\"T-shirt\");\n    cart.removeProduct(\"Jeans\");\n\n    return 0;\n}\n```\n\n### Visitor Pattern\n\nThe visitor pattern is a behavioral pattern used in software design to separate the algorithm for processing an object from the object itself. The pattern involves defining a visitor object that can visit and operate on a set of objects that implement a common interface.\n\n```cpp\n// Forward declaration of employee classes\nclass Manager;\nclass Engineer;\nclass Intern;\n\n// Abstract visitor class\nclass Visitor {\npublic:\n    virtual void visit(Manager* manager) = 0;\n    virtual void visit(Engineer* engineer) = 0;\n    virtual void visit(Intern* intern) = 0;\n};\n\n// Concrete employee classes\nclass Employee {\npublic:\n    virtual void accept(Visitor* visitor) = 0;\n};\n\nclass Manager : public Employee {\npublic:\n    void accept(Visitor* visitor) override {\n        visitor-\u003evisit(this);\n    }\n    int getSalary() const {\n        return 5000;\n    }\n};\n\nclass Engineer : public Employee {\npublic:\n    void accept(Visitor* visitor) override {\n        visitor-\u003evisit(this);\n    }\n    int getSalary() const {\n        return 3000;\n    }\n};\n\nclass Intern : public Employee {\npublic:\n    void accept(Visitor* visitor) override {\n        visitor-\u003evisit(this);\n    }\n    int getSalary() const {\n        return 1000;\n    }\n};\n\n// Concrete visitor class\nclass SalaryVisitor : public Visitor {\npublic:\n    void visit(Manager* manager) override {\n        totalSalary += manager-\u003egetSalary() * 2;\n    }\n    void visit(Engineer* engineer) override {\n        totalSalary += engineer-\u003egetSalary();\n    }\n    void visit(Intern* intern) override {\n        totalSalary += intern-\u003egetSalary() / 2;\n    }\n    int getTotalSalary() const {\n        return totalSalary;\n    }\nprivate:\n    int totalSalary = 0;\n};\n\n// Client code\nint main() {\n    std::vector\u003cEmployee*\u003e employees {\n        new Manager(),\n        new Engineer(),\n        new Intern(),\n        new Manager(),\n        new Engineer(),\n    };\n    SalaryVisitor visitor;\n    for (auto employee : employees) {\n        employee-\u003eaccept(\u0026visitor);\n    }\n    std::cout \u003c\u003c \"Total salary: \" \u003c\u003c visitor.getTotalSalary() \u003c\u003c std::endl;\n    for (auto employee : employees) {\n        delete employee;\n    }\n    return 0;\n}\n```\n\n### Mediator Pattern\n\nThe mediator pattern is a behavioral pattern used in software design to reduce the complexity of communication between objects by introducing a mediator object that encapsulates the communication logic. The mediator pattern promotes loose coupling between objects by eliminating the need for objects to communicate directly with each other.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n#include \u003cvector\u003e\n\n// Forward declaration of user classes\nclass User;\nclass ChatMediator;\n\n// Abstract mediator class\nclass ChatMediator {\npublic:\n    virtual void send(const std::string\u0026 message, User* sender) = 0;\n};\n\n// Concrete user classes\nclass User {\npublic:\n    User(const std::string\u0026 name, ChatMediator* mediator)\n        : name(name), mediator(mediator) {}\n\n    const std::string\u0026 getName() const {\n        return name;\n    }\n\n    void send(const std::string\u0026 message) {\n        mediator-\u003esend(message, this);\n    }\n\n    void receive(const std::string\u0026 message, User* sender) {\n        std::cout \u003c\u003c name \u003c\u003c \" received message from \" \u003c\u003c sender-\u003egetName() \u003c\u003c \": \" \u003c\u003c message \u003c\u003c std::endl;\n    }\n\nprivate:\n    std::string name;\n    ChatMediator* mediator;\n};\n\n// Concrete mediator class\nclass ChatRoom : public ChatMediator {\npublic:\n    void addUser(User* user) {\n        users.push_back(user);\n    }\n\n    void send(const std::string\u0026 message, User* sender) override {\n        for (auto user : users) {\n            if (user != sender) {\n                user-\u003ereceive(message, sender);\n            }\n        }\n    }\n\nprivate:\n    std::vector\u003cUser*\u003e users;\n};\n\n// Client code\nint main() {\n    ChatRoom chatRoom;\n    User alice(\"Alice\", \u0026chatRoom);\n    User bob(\"Bob\", \u0026chatRoom);\n    User charlie(\"Charlie\", \u0026chatRoom);\n\n    chatRoom.addUser(\u0026alice);\n    chatRoom.addUser(\u0026bob);\n    chatRoom.addUser(\u0026charlie);\n\n    alice.send(\"Hello everyone!\");\n    bob.send(\"Hey Alice!\");\n    charlie.send(\"Nice to meet you all!\");\n\n    return 0;\n}\n```\n\n### Memento Pattern\n\nThe Memento pattern is a behavioral design pattern that allows an object to save and restore its internal state without violating encapsulation. This pattern is useful when you want to be able to undo changes made to an object's state or when you need to be able to restore an object's state to a previous state.\nThe pattern involves three main components:\n\nOriginator: This is the object whose state needs to be saved and restored. It creates a memento object that contains a snapshot of its state.\n\nMemento: This is an object that stores the state of the originator. The memento object is typically read-only and can only be accessed by the originator.\n\nCaretaker: This is an object that is responsible for keeping track of mementos. It can save mementos, retrieve mementos, and pass mementos back to the originator to restore its state.\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n#include \u003cvector\u003e\n\n// Memento class\nclass DocumentMemento {\npublic:\n    DocumentMemento(const std::string\u0026 content) : content(content) {}\n    const std::string\u0026 getContent() const { return content; }\n\nprivate:\n    std::string content;\n};\n\n// Originator class\nclass TextEditor {\npublic:\n    void setContent(const std::string\u0026 content) {\n        this-\u003econtent = content;\n        std::cout \u003c\u003c \"Content set to: \" \u003c\u003c content \u003c\u003c std::endl;\n    }\n\n    DocumentMemento createMemento() const {\n        return DocumentMemento(content);\n    }\n\n    void restoreMemento(const DocumentMemento\u0026 memento) {\n        content = memento.getContent();\n        std::cout \u003c\u003c \"Content restored to: \" \u003c\u003c content \u003c\u003c std::endl;\n    }\n\nprivate:\n    std::string content;\n};\n\n// Caretaker class\nclass History {\npublic:\n    void addMemento(const DocumentMemento\u0026 memento) {\n        mementos.push_back(memento);\n    }\n\n    DocumentMemento getMemento(int index) const {\n        return mementos[index];\n    }\n\n    int getSize() const {\n        return mementos.size();\n    }\n\nprivate:\n    std::vector\u003cDocumentMemento\u003e mementos;\n};\n\n// Client code\nint main() {\n    TextEditor textEditor;\n    History history;\n\n    // Edit document and save mementos\n    textEditor.setContent(\"First version of the document\");\n    history.addMemento(textEditor.createMemento());\n\n    textEditor.setContent(\"Second version of the document\");\n    history.addMemento(textEditor.createMemento());\n\n    textEditor.setContent(\"Third version of the document\");\n    history.addMemento(textEditor.createMemento());\n\n    // Restore previous version of the document\n    int index = 1; // Index of the memento to restore\n    textEditor.restoreMemento(history.getMemento(index));\n\n    return 0;\n}\n```\n\n### Strategy Pattern\n\nThis pattern is used to define a family of algorithms, encapsulate each one, and make them interchangeable. The strategy pattern allows the algorithms to vary independently of the clients that use them, and it enables the selection of an algorithm at runtime based on specific needs.\n\n```cpp\n#include \u003ciostream\u003e\n\n// Weapon base class\nclass Weapon {\npublic:\n    virtual void useWeapon() = 0;\n};\n\n// Sword concrete class\nclass Sword : public Weapon {\npublic:\n    void useWeapon() {\n        std::cout \u003c\u003c \"Using a sword to attack!\" \u003c\u003c std::endl;\n    }\n};\n\n// Bow concrete class\nclass Bow : public Weapon {\npublic:\n    void useWeapon() {\n        std::cout \u003c\u003c \"Using a bow to attack!\" \u003c\u003c std::endl;\n    }\n};\n\n// Character class\nclass Character {\npublic:\n    Character(Weapon* weapon) : weapon(weapon) {}\n\n    void setWeapon(Weapon* weapon) {\n        this-\u003eweapon = weapon;\n    }\n\n    void attack() {\n        weapon-\u003euseWeapon();\n    }\n\nprivate:\n    Weapon* weapon;\n};\n\n// Client code\nint main() {\n    // Create a character with a sword\n    Sword sword;\n    Character character(\u0026sword);\n    character.attack();\n\n    // Switch the character's weapon to a bow\n    Bow bow;\n    character.setWeapon(\u0026bow);\n    character.attack();\n\n    return 0;\n}\n```\n\n### Template Metohd Pattern\n\nThe template method pattern is used to define the skeleton of an algorithm in a base class, with certain steps deferred to subclasses. This pattern allows subclasses to redefine certain steps of the algorithm without changing its overall structure.\n\n```cpp\n#include \u003ciostream\u003e\n\n// Report base class\nclass Report {\npublic:\n    // Template method\n    void createReport() {\n        createHeader();\n        createBody();\n        createFooter();\n    }\n\n    // Abstract methods\n    virtual void createHeader() = 0;\n    virtual void createBody() = 0;\n    virtual void createFooter() = 0;\n};\n\n// PDF report class\nclass PdfReport : public Report {\npublic:\n    // Override abstract methods to create PDF-specific content\n    void createHeader() {\n        std::cout \u003c\u003c \"Creating PDF header...\" \u003c\u003c std::endl;\n    }\n\n    void createBody() {\n        std::cout \u003c\u003c \"Creating PDF body...\" \u003c\u003c std::endl;\n    }\n\n    void createFooter() {\n        std::cout \u003c\u003c \"Creating PDF footer...\" \u003c\u003c std::endl;\n    }\n};\n\n// CSV report class\nclass CsvReport : public Report {\npublic:\n    // Override abstract methods to create CSV-specific content\n    void createHeader() {\n        std::cout \u003c\u003c \"Creating CSV header...\" \u003c\u003c std::endl;\n    }\n\n    void createBody() {\n        std::cout \u003c\u003c \"Creating CSV body...\" \u003c\u003c std::endl;\n    }\n\n    void createFooter() {\n        std::cout \u003c\u003c \"Creating CSV footer...\" \u003c\u003c std::endl;\n    }\n};\n\n// Client code\nint main() {\n    // Create a PDF report and create it\n    PdfReport pdfReport;\n    pdfReport.createReport();\n\n    // Create a CSV report and create it\n    CsvReport csvReport;\n    csvReport.createReport();\n\n    return 0;\n}\n```\n\n# Software Architectural Patterns\n\nA software architectural pattern is a general, reusable solution to a commonly occurring problem in software architecture. It provides a template or a blueprint for how to organize and structure software systems to achieve a set of desired qualities, such as maintainability, scalability, flexibility, and modifiability.\n\n## Client-Server Architectures\n\nClient-server architecture is a common software architecture pattern where a client application communicates with a server over a network. In this pattern, the client is typically a user-facing application that runs on a desktop or mobile device, while the server is a backend system that provides services to the client.\n\n## Model-view controller Architecture\n\nModel-View-Controller (MVC) separates an application into three interconnected components: a model that represents the data and business logic, a view that displays the user interface, and a controller that handles user input and updates the model and view accordingly.\n\n## Layered Architecture\n\nLayered architecture: divides an application into multiple layers, each responsible for a specific set of functions. This helps to modularize the system, making it easier to manage and maintain.\n\n## Enterprise Architecture\n\nEnterprise architecture (EA) is a discipline that involves the planning, design, implementation, and management of an organization's information technology (IT) infrastructure and related resources to align with the organization's overall business goals and objectives.\n\nEnterprise architecture takes a holistic view of the entire organization and its environment, including people, processes, information, technology, and other resources. It provides a framework for organizations to plan and manage their IT investments, ensure alignment between IT and business strategies, and enable effective decision-making.\n\n## Business Architecture\n\nBusiness architecture is a component of enterprise architecture that describes the organization's business processes, capabilities, goals, and strategies, and how they relate to the overall IT architecture. Business architecture provides a framework for understanding and managing the organization's operations, and how they contribute to achieving the organization's overall objectives.\n\n## Information System Architecture\n\nInformation system architecture is the design and structure of an organization's information systems, including hardware, software, databases, networks, and other components. It provides a framework for organizing and integrating information and technology resources to meet the organization's objectives.\n\n## Application Architecture \u0026 Data Architecture\n\nApplication architecture refers to the structure and design of the software applications used by an organization, including their components, interactions, and interfaces. Application architecture includes several key components, including:\n\n1. User interface: defines the way users interact with the application, including the layout, design, and functionality of the application's interface.\n\n2. Business logic: describes the rules and algorithms that govern the application's behavior and processing of data.\n\n3. Data access: specifies how the application retrieves and manipulates data, including the data storage technologies used.\n\n4. Integration: defines how the application interacts with other applications and systems, including the use of APIs, web services, and other integration technologies.\n\nData architecture, on the other hand, refers to the design and management of an organization's data resources, including how data is stored, processed, and managed. Data architecture includes several key components, including:\nData models: describes the structure and relationships between different types of data, including entities, attributes, and relationships.\n\n1. Data models: describes the structure and relationships between different types of data, including entities, attributes, and relationships.\n\n2. Data storage: defines the physical storage of data, including the use of databases, data warehouses, and other storage technologies.\n\n3. Data integration: specifies how data from different sources is combined and transformed to provide a unified view of the organization's data.\n\n4. Data security: describes the measures used to protect the organization's data from unauthorized access or theft.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhtmujahid%2Fsoftware-design-patterns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhtmujahid%2Fsoftware-design-patterns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhtmujahid%2Fsoftware-design-patterns/lists"}