├── BehaviroalPatterns ├── chain-of-responsibility │ ├── ChainOfResponsibility.cxx │ └── README.md ├── command │ ├── Command.cxx │ └── README.md ├── interpreter │ ├── Interpreter.cxx │ └── README.md ├── iterator │ ├── Iterator.cxx │ └── README.md ├── mediator │ ├── Mediator.cxx │ └── README.md ├── memento │ ├── Memento.cxx │ └── README.md ├── observer │ ├── Observer.cxx │ └── README.md ├── state │ ├── README.md │ └── State.cxx ├── strategy │ ├── README.md │ └── Strategy.cxx ├── template-method │ ├── README.md │ └── TemplateMethod.cxx └── visitor │ ├── README.md │ └── Visitor.cxx ├── CMakeLists.txt ├── CreationalPatterns ├── abstract-factory │ ├── AbstractFactoryPattern.cxx │ └── README.md ├── builder │ ├── Builder.cxx │ └── README.md ├── factory-method │ ├── FactoryMethod.cxx │ └── README.md ├── prototype │ ├── Prototype.cxx │ └── README.md └── singleton │ ├── README.md │ └── Singleton.cxx ├── LICENSE ├── README.md ├── StructuralPatterns ├── adapter │ ├── ClassAdapter.cxx │ ├── ObjectAdapter.cxx │ └── README.md ├── bridge │ ├── Bridge.cxx │ └── README.md ├── composite │ ├── Composite.cxx │ └── README.md ├── decorator │ ├── Decorator.cxx │ └── README.md ├── facade │ ├── Facade.cxx │ └── README.md ├── flyweight │ ├── Flyweight.cxx │ └── README.md └── proxy │ ├── Proxy.cxx │ └── README.md └── images ├── AbstractFactory.png ├── Adapter.png ├── Bridge.png ├── Builder.png ├── ChainOfResponsibility.png ├── Command.PNG ├── Composite.png ├── Decorator.png ├── Facade.png ├── Factory.png ├── Flyweight.png ├── Interpreter.PNG ├── Iterator.png ├── Mediator.PNG ├── Memento.PNG ├── Observer.PNG ├── Prototype.png ├── Proxy.png ├── SingletonPattern.png ├── State.PNG ├── Strategy.PNG ├── TemplateMethod.png └── Visitor.PNG /BehaviroalPatterns/chain-of-responsibility/ChainOfResponsibility.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Handler { 12 | public: 13 | virtual ~Handler() {} 14 | 15 | void setSuccessor(Handler *s) { 16 | successor_ = s; 17 | } 18 | 19 | Handler* getSuccessor() { 20 | return successor_; 21 | } 22 | 23 | virtual void handleRequest() = 0; 24 | private: 25 | Handler *successor_; 26 | }; 27 | 28 | class ConcreteHandler1 : public Handler { 29 | public: 30 | ~ConcreteHandler1() {} 31 | 32 | void handleRequest() { 33 | if (!this->getSuccessor()) { 34 | std::cout << "This is handled by Concrete Handler 1" << std::endl; 35 | } 36 | else { 37 | std::cout << "This will be handled by the Successor" << std::endl; 38 | this->getSuccessor()->handleRequest(); 39 | } 40 | } 41 | }; 42 | 43 | class ConcreteHandler2 : public Handler { 44 | public: 45 | ~ConcreteHandler2() {} 46 | 47 | void handleRequest() { 48 | if (!this->getSuccessor()) { 49 | std::cout << "This is handled by Concrete Handler 2" << std::endl; 50 | } 51 | else { 52 | std::cout << "This will be handled by the Successor" << std::endl; 53 | this->getSuccessor()->handleRequest(); 54 | } 55 | } 56 | }; 57 | 58 | int main() { 59 | Handler* h1 = new ConcreteHandler1(); 60 | Handler* h2 = new ConcreteHandler2(); 61 | 62 | h1->setSuccessor(h2); 63 | h1->handleRequest(); 64 | } -------------------------------------------------------------------------------- /BehaviroalPatterns/chain-of-responsibility/README.md: -------------------------------------------------------------------------------- 1 | ## Chain of Responsibility 2 | 3 | Chain of Responsibility pattern avoids coupling the sender of a request to its receiver 4 | by giving more than one object a chance to handle the request. The pattern chains 5 | the receiving objects and passes the request along the chain until an object handles it. 6 | It has a behavioral purpose and deals with relationships between objects. 7 | 8 | ### When to use 9 | 10 | * more than one object may handle a request, and the handler should be ascertained automatically 11 | * you want to issue a request to one of several objects without specifying the receiver explicitly 12 | * the set of objects that can handle a request should be specified dynamically -------------------------------------------------------------------------------- /BehaviroalPatterns/command/Command.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class Receiver { 11 | public: 12 | void action() { 13 | std::cout << "Recevier: execute action" << std::endl; 14 | } 15 | }; 16 | 17 | class Command { 18 | public: 19 | virtual ~Command() {} 20 | 21 | virtual void execute() = 0; 22 | }; 23 | 24 | class ConcreteCommand : public Command { 25 | public: 26 | ConcreteCommand(Receiver *r) : receiver_(r) {}; 27 | ~ConcreteCommand() { 28 | if (!receiver_) { 29 | delete receiver_; 30 | } 31 | } 32 | 33 | void execute() { 34 | receiver_->action(); 35 | } 36 | private: 37 | Receiver* receiver_; 38 | }; 39 | 40 | class Invoker { 41 | public: 42 | void setCommand(Command* c) { 43 | command_ = c; 44 | } 45 | 46 | void executeCommand() { 47 | if (command_) command_->execute(); 48 | } 49 | 50 | private: 51 | Command* command_; 52 | }; 53 | 54 | int main() { 55 | Receiver* receiver = new Receiver(); 56 | Command *command = new ConcreteCommand(receiver); 57 | 58 | Invoker invoker; 59 | invoker.setCommand(command); 60 | invoker.executeCommand(); 61 | } -------------------------------------------------------------------------------- /BehaviroalPatterns/command/README.md: -------------------------------------------------------------------------------- 1 | ## Command 2 | 3 | Command pattern encapsulates a request as an object, thereby letting you parameterize 4 | clients with different requests, queue or log requests, and supports undoable 5 | operations. The pattern has a behavioral purpose and deals with relationships between objects. 6 | 7 | ### When to use 8 | 9 | * want to parameterize objects by an action to perform 10 | * want to specify, queue, and execute requests at different times 11 | * support undo 12 | * support logging changes so that they can be reapplied in case of a system crash 13 | * structure a system around high-level operations built on primitives operations 14 | -------------------------------------------------------------------------------- /BehaviroalPatterns/interpreter/Interpreter.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | /* 12 | * Interpreter example: 13 | * A->true, B->false, AB->false, C->true, AC->true 14 | */ 15 | class Context { 16 | public: 17 | void set(char var, bool value) { 18 | maps.insert(std::make_pair(var, value)); 19 | } 20 | 21 | char get(char var) { 22 | return maps[var]; 23 | } 24 | private: 25 | std::unordered_map maps; 26 | }; 27 | 28 | class AbstractExpression { 29 | public: 30 | virtual ~AbstractExpression() {} 31 | 32 | virtual bool interpret(Context* const context) = 0; 33 | }; 34 | 35 | class TerminalExpression : public AbstractExpression { 36 | public: 37 | TerminalExpression(char var) : var_(var) {} 38 | ~TerminalExpression() {} 39 | 40 | bool interpret(Context* const context) { 41 | return context->get(var_); 42 | } 43 | private: 44 | char var_; 45 | }; 46 | 47 | class NonTerminalExpression : public AbstractExpression { 48 | public: 49 | NonTerminalExpression(AbstractExpression* f, AbstractExpression* s) 50 | : first(f), second(s) {} 51 | 52 | ~NonTerminalExpression() { 53 | if (first) delete first; 54 | if (second) delete second; 55 | } 56 | 57 | bool interpret(Context* const context) { 58 | return first->interpret(context) && second->interpret(context); 59 | } 60 | private: 61 | AbstractExpression* first; 62 | AbstractExpression* second; 63 | }; 64 | 65 | int main() { 66 | Context context; 67 | context.set('A', true); 68 | context.set('B', false); 69 | context.set('C', true); 70 | 71 | AbstractExpression* expressionA = new TerminalExpression('A'); 72 | AbstractExpression* expressionB = new TerminalExpression('B'); 73 | AbstractExpression* expressionC = new TerminalExpression('C'); 74 | 75 | AbstractExpression* expressionAB = new NonTerminalExpression(expressionA, expressionB); 76 | AbstractExpression* expressionAC = new NonTerminalExpression(expressionA, expressionC); 77 | 78 | std::cout << "A -> " << expressionA->interpret(&context) << std::endl; 79 | std::cout << "B -> " << expressionB->interpret(&context) << std::endl; 80 | std::cout << "C -> " << expressionC->interpret(&context) << std::endl; 81 | 82 | std::cout << "AB -> " << expressionAB->interpret(&context) << std::endl; 83 | std::cout << "AC -> " << expressionAC->interpret(&context) << std::endl; 84 | } -------------------------------------------------------------------------------- /BehaviroalPatterns/interpreter/README.md: -------------------------------------------------------------------------------- 1 | ## Interpreter 2 | 3 | Given a language, the pattern defines a represention for its grammar along with an 4 | interpreter that uses the representation to interpret sentences in the language. 5 | The Interpreter pattern has behavioral purpose and applies to the classes. 6 | 7 | ### When to use 8 | 9 | * when the grammar is simple (in case of complex grammars, there are better alternatives) 10 | * efficiency is not a critical concern -------------------------------------------------------------------------------- /BehaviroalPatterns/iterator/Iterator.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Iterator; 12 | class ConcreteIterator; 13 | 14 | class Aggregate { 15 | public: 16 | virtual ~Aggregate() {} 17 | 18 | virtual Iterator* createIterator() = 0; 19 | }; 20 | 21 | class ConcreteAggregate : public Aggregate { 22 | public: 23 | ConcreteAggregate(int N) { 24 | for (int i = 0; i < N; ++i) { 25 | objs_.emplace_back(i); 26 | } 27 | } 28 | ~ConcreteAggregate() {} 29 | 30 | Iterator* createIterator(); 31 | 32 | int getItem(int idx) { return objs_.at(idx); } 33 | 34 | unsigned int getSize() { return objs_.size(); } 35 | 36 | void addItem(int obj) { objs_.emplace_back(obj); } 37 | 38 | private: 39 | std::vector objs_; 40 | }; 41 | 42 | class Iterator { 43 | public: 44 | virtual ~Iterator() {} 45 | 46 | virtual void first() = 0; 47 | virtual void next() = 0; 48 | virtual bool isDone() = 0; 49 | virtual int currentItem() = 0; 50 | }; 51 | 52 | class ConcreteIterator : public Iterator { 53 | public: 54 | ConcreteIterator(ConcreteAggregate *ag) 55 | : cag_(ag), index_(0) {} 56 | 57 | void first() { 58 | index_ = 0; 59 | } 60 | 61 | void next() { 62 | ++index_; 63 | } 64 | 65 | bool isDone() { 66 | return index_ >= cag_->getSize(); 67 | } 68 | 69 | int currentItem() { 70 | return cag_->getItem(index_); 71 | } 72 | private: 73 | ConcreteAggregate *cag_; 74 | int index_; 75 | }; 76 | 77 | Iterator * ConcreteAggregate::createIterator() { 78 | return new ConcreteIterator(this); 79 | } 80 | 81 | int main() { 82 | ConcreteAggregate *cag = new ConcreteAggregate(10); 83 | cag->addItem(99); 84 | 85 | Iterator* it = cag->createIterator(); 86 | for ( ; !it->isDone(); it->next()) { 87 | std::cout << "Item value: " << it->currentItem() << std::endl; 88 | } 89 | 90 | } 91 | 92 | 93 | -------------------------------------------------------------------------------- /BehaviroalPatterns/iterator/README.md: -------------------------------------------------------------------------------- 1 | ## Iterator 2 | 3 | Iterator pattern has behavioral purpose and applies to objects. The pattern provides 4 | a way to access the elements of an aggregate object sequentially without exposing 5 | its underlying representation. 6 | 7 | ### When to use 8 | 9 | * to access an aggregate object's contents without exposing its internal representation 10 | * to support multiple traversals of aggregate objects 11 | * to provide a uniform interface for traversing different aggregate structures 12 | (to support polymorphic iteration) -------------------------------------------------------------------------------- /BehaviroalPatterns/mediator/Mediator.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | class Mediator; 13 | 14 | class Colleague { 15 | public: 16 | Colleague(Mediator* const m, unsigned int i) 17 | : mediator_(m), id_(i) {} 18 | 19 | virtual ~Colleague() = default; 20 | 21 | unsigned int getId() { 22 | return id_; 23 | } 24 | 25 | virtual void sendMsg(std::string) = 0; 26 | virtual void receiveMsg(std::string) = 0; 27 | 28 | protected: 29 | Mediator* mediator_; 30 | unsigned int id_; 31 | }; 32 | 33 | class ConcreteColleague : public Colleague { 34 | public: 35 | ConcreteColleague(Mediator* const m, unsigned int i) 36 | : Colleague(m, i) {} 37 | 38 | ~ConcreteColleague() = default; 39 | 40 | void sendMsg(std::string msg) override; 41 | 42 | void receiveMsg(std::string msg) override { 43 | std::cout << "Message: " << msg << " is received by Colleague(id=" << this->getId() << ")" << std::endl; 44 | } 45 | }; 46 | 47 | class Mediator { 48 | public: 49 | virtual ~Mediator() = default; 50 | 51 | virtual void add(Colleague* const c) = 0; 52 | 53 | virtual void distribute(Colleague* const sender, const std::string& msg) = 0; 54 | }; 55 | 56 | class ConcreteMediator : public Mediator { 57 | public: 58 | ~ConcreteMediator() { 59 | for (unsigned int i = 0; i < colleagues_.size(); ++i) { 60 | delete colleagues_[i]; 61 | } 62 | colleagues_.clear(); 63 | } 64 | 65 | void add(Colleague* const c) { 66 | colleagues_.push_back(c); 67 | } 68 | 69 | void distribute(Colleague* const sender, const std::string& msg) { 70 | for (auto colleague : colleagues_) { 71 | if (colleague->getId() != sender->getId()) { 72 | colleague->receiveMsg(msg); 73 | } 74 | } 75 | } 76 | private: 77 | std::vector colleagues_; 78 | }; 79 | 80 | void ConcreteColleague::sendMsg(std::string msg) { 81 | std::cout << "Message: " << msg << " is sent by Colleague(id=" << this->getId() << ")" << std::endl; 82 | mediator_->distribute(this, msg); 83 | } 84 | 85 | int main() { 86 | Mediator *mediator = new ConcreteMediator(); 87 | 88 | Colleague *colleague1 = new ConcreteColleague(mediator, 1); 89 | Colleague *colleague2 = new ConcreteColleague(mediator, 2); 90 | Colleague *colleague3 = new ConcreteColleague(mediator, 3); 91 | 92 | mediator->add(colleague1); 93 | mediator->add(colleague2); 94 | mediator->add(colleague3); 95 | 96 | colleague1->sendMsg("Hello"); 97 | colleague2->sendMsg("World"); 98 | colleague3->sendMsg("Mediator Pattern"); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /BehaviroalPatterns/mediator/README.md: -------------------------------------------------------------------------------- 1 | ## Mediator 2 | 3 | Mediator pattern has behavioral purpose and applies on objects. 4 | The pattern defines an object that encapsulates how a set of objects interact. 5 | It promotes loose coupling by keeping objects from referring to each 6 | other explicitly, and it lets you vary their interaction independently. 7 | 8 | ### When to use 9 | 10 | * a set of objects communicate in well-defined but complex ways 11 | * reusing an object is difficult because it refers to and communicates with many other objects 12 | * a behavior that's distributed between several classes should be customizable without a lot of subclassing -------------------------------------------------------------------------------- /BehaviroalPatterns/memento/Memento.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Memento { 12 | private: 13 | friend class Originator; 14 | 15 | Memento(int s) : state_(s) {} 16 | 17 | void setState(int s) { 18 | state_ = s; 19 | } 20 | 21 | int getState() { 22 | return state_; 23 | } 24 | private: 25 | int state_; 26 | }; 27 | 28 | class Originator { 29 | public: 30 | void setState(int s) { 31 | state_ = s; 32 | } 33 | 34 | int getState() { 35 | return state_; 36 | } 37 | 38 | void setMemento(Memento* const m) { 39 | state_ = m->getState(); 40 | } 41 | 42 | Memento* createMemento() { 43 | return new Memento(state_); 44 | } 45 | 46 | int getMementoState(Memento* const m) { 47 | return m->getState(); 48 | } 49 | 50 | private: 51 | int state_; 52 | }; 53 | 54 | class CareTaker { 55 | public: 56 | CareTaker(Originator* const o) : originator_(o) {} 57 | 58 | ~CareTaker() { 59 | for (auto m : historySaved_) { 60 | if (m) delete m; 61 | } 62 | for (auto m : historyUndo_) { 63 | if (m) delete m; 64 | } 65 | historySaved_.clear(); 66 | historyUndo_.clear(); 67 | } 68 | 69 | void save() { 70 | std::cout << "Save state: " << originator_->getState() << std::endl; 71 | historySaved_.push_back(originator_->createMemento()); 72 | } 73 | 74 | void printSavedStates() { 75 | std::cout << "Saved states:" << std::endl; 76 | if (historySaved_.empty()) { 77 | std::cout << "It's empty" << std::endl; 78 | } 79 | for (auto m : historySaved_) { 80 | std::cout << "state " << originator_->getMementoState(m) << std::endl; 81 | } 82 | } 83 | 84 | void undo() { 85 | if (historySaved_.empty()) { 86 | std::cout << "Unable to undo state." << std::endl; 87 | return; 88 | } 89 | Memento* m = historySaved_.back(); 90 | originator_->setMemento(m); 91 | std::cout << "Undo state: " << originator_->getState() << std::endl; 92 | 93 | historySaved_.pop_back(); 94 | historyUndo_.push_back(m); 95 | } 96 | 97 | void redo() { 98 | if (historyUndo_.empty()) { 99 | std::cout << "Unable to redo state." << std::endl; 100 | return; 101 | } 102 | Memento* m = historyUndo_.back(); 103 | originator_->setMemento(m); 104 | std::cout << "Redo state: " << originator_->getState() << std::endl; 105 | 106 | historyUndo_.pop_back(); 107 | historySaved_.push_back(m); 108 | } 109 | 110 | private: 111 | Originator* originator_; 112 | std::vector historySaved_; // for undo 113 | std::vector historyUndo_; // for redo 114 | }; 115 | 116 | int main() { 117 | Originator *originator = new Originator(); 118 | CareTaker *careTaker = new CareTaker( originator); 119 | 120 | originator->setState(0); 121 | careTaker->save(); 122 | originator->setState(1); 123 | careTaker->save(); 124 | originator->setState(2); 125 | careTaker->save(); 126 | 127 | careTaker->printSavedStates(); 128 | 129 | careTaker->undo(); 130 | careTaker->printSavedStates(); 131 | 132 | careTaker->redo(); 133 | careTaker->printSavedStates(); 134 | 135 | careTaker->undo(); 136 | careTaker->undo(); 137 | careTaker->undo(); 138 | careTaker->printSavedStates(); 139 | } 140 | -------------------------------------------------------------------------------- /BehaviroalPatterns/memento/README.md: -------------------------------------------------------------------------------- 1 | ## Memento 2 | 3 | Memento without violating encapsulation, captures and externalizes an object's internal 4 | state so that the object can be restored to this state later. The pattern has behavioral 5 | purpose and applies to the objects. 6 | 7 | ### When to use 8 | 9 | * a snapshot of an object's state must be saved so that it can be restored to that state later 10 | * a direct interface to obtaining the state would expose implementation details and break the object's encapsulation -------------------------------------------------------------------------------- /BehaviroalPatterns/observer/Observer.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Subject; 12 | 13 | class Observer { 14 | public: 15 | Observer(const int id) : id_(id) {} 16 | virtual ~Observer() {} 17 | 18 | virtual int getState() = 0; 19 | virtual void update(Subject* subject) = 0; 20 | virtual int getId() = 0; 21 | protected: 22 | int id_; 23 | }; 24 | 25 | class ConcreteObserver : public Observer { 26 | public: 27 | ConcreteObserver(const int state, const int id) 28 | : object_state_(state), Observer(id) {} 29 | ~ConcreteObserver() {} 30 | 31 | int getState() { 32 | return object_state_; 33 | } 34 | 35 | int getId() { 36 | return id_; 37 | } 38 | 39 | void update(Subject* subject); 40 | private: 41 | int object_state_; 42 | }; 43 | 44 | class Subject { 45 | public: 46 | virtual ~Subject() {} 47 | 48 | void attach(Observer* observer) { 49 | observers_.push_back(observer); 50 | } 51 | 52 | void detach(const int id) { 53 | for (auto it = observers_.begin(); it != observers_.end(); ++it) { 54 | if ((*it)->getId() == id) { 55 | observers_.erase(it); 56 | } 57 | } 58 | } 59 | 60 | void notify() { 61 | for (auto observer : observers_) { 62 | observer->update(this); 63 | } 64 | } 65 | 66 | virtual int getState() = 0; 67 | virtual void setState(const int state) = 0; 68 | private: 69 | std::vector observers_; 70 | }; 71 | 72 | class ConcreteSubject : public Subject { 73 | public: 74 | ~ConcreteSubject() {} 75 | 76 | int getState() { 77 | return subject_state_; 78 | } 79 | 80 | void setState(const int state) { 81 | subject_state_ = state; 82 | } 83 | private: 84 | int subject_state_; 85 | }; 86 | 87 | void ConcreteObserver::update(Subject *subject) { 88 | object_state_ = subject->getState(); 89 | std::cout << "Observer(id=" << id_ << ") update state to: " << object_state_ << std::endl; 90 | } 91 | 92 | int main() { 93 | ConcreteObserver observer1(1000, 1); 94 | ConcreteObserver observer2(2000, 2); 95 | 96 | std::cout << "Observer1 state: " << observer1.getState() << std::endl; 97 | std::cout << "Observer2 state: " << observer2.getState() << std::endl; 98 | 99 | Subject* subject = new ConcreteSubject(); 100 | subject->attach(&observer1); 101 | subject->attach(&observer2); 102 | 103 | subject->setState(10); 104 | subject->notify(); 105 | 106 | std::cout << "Observer1 state: " << observer1.getState() << std::endl; 107 | std::cout << "Observer2 state: " << observer2.getState() << std::endl; 108 | 109 | subject->detach(0); 110 | subject->setState(100); 111 | subject->notify(); 112 | 113 | std::cout << "Observer1 state: " << observer1.getState() << std::endl; 114 | std::cout << "Observer2 state: " << observer2.getState() << std::endl; 115 | } 116 | -------------------------------------------------------------------------------- /BehaviroalPatterns/observer/README.md: -------------------------------------------------------------------------------- 1 | ## Observer 2 | 3 | Observer defines a one-to-many dependency between objects so that when one object 4 | changes state, all its dependents are notified and updated automatically. The pattern 5 | has behavioral purpose and applies to the objects. 6 | 7 | ### When to use 8 | 9 | * when an abstraction has two aspects, one dependent on the other 10 | * when a change to one object requires changing others, and you don't know how many objects need to be changed 11 | * when an object should be able to notify other objects without making assumptions about who these objects are -------------------------------------------------------------------------------- /BehaviroalPatterns/state/README.md: -------------------------------------------------------------------------------- 1 | ## State 2 | 3 | The pattern allows an object to alter its behavior when its internal state changes. 4 | The object will appear to change its class. It has behavioral purpose and applies 5 | to the objects. 6 | 7 | ### When to use 8 | 9 | * when an object's behavior depends on its state, and it must change its behavior at run-time depending on that state 10 | * operations have large, multipart conditional statements that depend on the object's state -------------------------------------------------------------------------------- /BehaviroalPatterns/state/State.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class State { 11 | public: 12 | virtual ~State() {} 13 | 14 | virtual void handle() = 0; 15 | }; 16 | 17 | class ConcreteStateA : public State { 18 | ~ConcreteStateA() {} 19 | 20 | void handle() { 21 | std::cout << "State A handled." << std::endl; 22 | } 23 | }; 24 | 25 | class ConcreteStateB : public State { 26 | ~ConcreteStateB() {} 27 | 28 | void handle() { 29 | std::cout << "State B handled." << std::endl; 30 | } 31 | }; 32 | 33 | class Context { 34 | public: 35 | Context() : state() {} 36 | ~Context() { 37 | if (state) { 38 | delete state; 39 | } 40 | } 41 | 42 | void setState(State* const s) { 43 | if (state) { 44 | delete state; 45 | } 46 | state = s; 47 | } 48 | 49 | void request() { 50 | state->handle(); 51 | } 52 | 53 | private: 54 | State* state; 55 | }; 56 | 57 | int main() { 58 | Context* context = new Context(); 59 | 60 | context->setState(new ConcreteStateA()); 61 | context->request(); 62 | 63 | context->setState(new ConcreteStateB()); 64 | context->request(); 65 | } -------------------------------------------------------------------------------- /BehaviroalPatterns/strategy/README.md: -------------------------------------------------------------------------------- 1 | ## Strategy 2 | 3 | Strategy defines a family of algorithms, encapsulates each one, and makes them 4 | interchangeable. It lets the algorithm vary independently fromclients that use it. 5 | The pattern has behavioral purpose and applies to the objects. 6 | 7 | ### When to use 8 | 9 | * many related classes differ only in their behavior 10 | * you need different variants of an algorithm 11 | * an algorithm uses data that clients shouldn't know about -------------------------------------------------------------------------------- /BehaviroalPatterns/strategy/Strategy.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class Strategy { 11 | public: 12 | virtual ~Strategy() {} 13 | virtual void algorithmInterface() = 0; 14 | }; 15 | 16 | class ConcreteStrategyA : public Strategy { 17 | ~ConcreteStrategyA() {} 18 | 19 | void algorithmInterface() { 20 | std::cout << "Concrete Strategy A" << std::endl; 21 | } 22 | }; 23 | 24 | class ConcreteStrategyB : public Strategy { 25 | ~ConcreteStrategyB() {} 26 | 27 | void algorithmInterface() { 28 | std::cout << "Concrete Strategy B" << std::endl; 29 | } 30 | }; 31 | 32 | class ConcreteStrategyC : public Strategy { 33 | ~ConcreteStrategyC() {} 34 | 35 | void algorithmInterface() { 36 | std::cout << "Concrete Strategy C" << std::endl; 37 | } 38 | }; 39 | 40 | class Context { 41 | public: 42 | Context(Strategy* s) : strategy(s) {} 43 | ~Context() { 44 | delete strategy; 45 | } 46 | 47 | void contextInterface() { 48 | strategy->algorithmInterface(); 49 | } 50 | private: 51 | Strategy* strategy; 52 | }; 53 | 54 | int main() { 55 | Context context(new ConcreteStrategyA()); 56 | context.contextInterface(); 57 | } -------------------------------------------------------------------------------- /BehaviroalPatterns/template-method/README.md: -------------------------------------------------------------------------------- 1 | ## Template Method 2 | 3 | Template method defines the skeleton of an algorithm in an operation, deferring some 4 | steps to subclasses. It lets subclasses redefine certain steps of an algorithm 5 | without changing the algorithm's structure. The pattern has behavioral purpose and 6 | applies to the classes. 7 | 8 | ### When to use 9 | 10 | * to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary 11 | * when common behavior among subclasses should be factored and localizedin a common class to avoid code duplication 12 | * to control subclasses extensions -------------------------------------------------------------------------------- /BehaviroalPatterns/template-method/TemplateMethod.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class AbstractClass { 11 | public: 12 | virtual ~AbstractClass() {} 13 | 14 | void templateMethod() { 15 | primitiveOperation1(); 16 | primitiveOperation2(); 17 | } 18 | 19 | virtual void primitiveOperation1() = 0; 20 | virtual void primitiveOperation2() = 0; 21 | }; 22 | 23 | class ConcreteClass : public AbstractClass { 24 | public: 25 | ~ConcreteClass() {} 26 | 27 | void primitiveOperation1() { 28 | std::cout << "Primitive Operation 1" << std::endl; 29 | } 30 | 31 | void primitiveOperation2() { 32 | std::cout << "Primitive Operation 2" << std::endl; 33 | } 34 | }; 35 | 36 | int main() { 37 | AbstractClass *templateClass = new ConcreteClass(); 38 | templateClass->templateMethod(); 39 | } -------------------------------------------------------------------------------- /BehaviroalPatterns/visitor/README.md: -------------------------------------------------------------------------------- 1 | ## Visitor 2 | 3 | Visitor represents an operation to be performed on the elements of an object 4 | structure. It lets you define a new operation without changing the classes of 5 | the elements on which it operates. The pattern has behavioral purpose and applies 6 | to the objects. 7 | 8 | ### When to use 9 | 10 | * an object structure contains many classes of objects with differing interfaces, 11 | and you want to perform operations on these objects that depend on their concrete classes 12 | * many distinct and unrelated operations need to be performed on objects in an object structure, 13 | and you want to avoid "polluting" their classes with these operations 14 | * the classes defining the object structure rarely change, but you often want 15 | to define new operations over the structure -------------------------------------------------------------------------------- /BehaviroalPatterns/visitor/Visitor.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class Element; 11 | class ConcreteElementA; 12 | class ConcreteElementB; 13 | 14 | class Vistor { 15 | public: 16 | virtual ~Vistor() {} 17 | 18 | virtual void vistorElementA(ConcreteElementA* const element) = 0; 19 | virtual void vistorElementB(ConcreteElementB* const element) = 0; 20 | }; 21 | 22 | class ConcreteVistor1 : public Vistor { 23 | public: 24 | ~ConcreteVistor1() {} 25 | 26 | void vistorElementA(ConcreteElementA* const element); 27 | void vistorElementB(ConcreteElementB* const element); 28 | }; 29 | 30 | class ConcreteVistor2 : public Vistor { 31 | public: 32 | ~ConcreteVistor2() {} 33 | 34 | void vistorElementA(ConcreteElementA* const element); 35 | void vistorElementB(ConcreteElementB* const element); 36 | }; 37 | 38 | class Element { 39 | public: 40 | virtual ~Element() {} 41 | 42 | virtual void accept(Vistor& v) = 0; 43 | }; 44 | 45 | class ConcreteElementA : public Element { 46 | public: 47 | ConcreteElementA(const std::string& data) 48 | : data_(data) {} 49 | ~ConcreteElementA() {} 50 | 51 | void accept(Vistor& v) { 52 | v.vistorElementA(this); 53 | } 54 | 55 | std::string getData() { 56 | return data_; 57 | } 58 | private: 59 | std::string data_; 60 | }; 61 | 62 | class ConcreteElementB : public Element { 63 | public: 64 | ConcreteElementB(const std::string& data) 65 | : data_(data) {} 66 | ~ConcreteElementB() {} 67 | 68 | void accept(Vistor& v) { 69 | v.vistorElementB(this); 70 | } 71 | 72 | std::string getData() { 73 | return data_; 74 | } 75 | private: 76 | std::string data_; 77 | }; 78 | 79 | void ConcreteVistor1::vistorElementA(ConcreteElementA *const element) { 80 | std::cout << "Concrete Vistor 1 : Element A visited." << std::endl; 81 | std::cout << "Element A data: " << element->getData() << std::endl; 82 | } 83 | 84 | void ConcreteVistor1::vistorElementB(ConcreteElementB *const element) { 85 | std::cout << "Concrete Vistor 1 : Element B visited." << std::endl; 86 | std::cout << "Element B data: " << element->getData() << std::endl; 87 | } 88 | 89 | void ConcreteVistor2::vistorElementA(ConcreteElementA *const element) { 90 | std::cout << "Concrete Vistor 2 : Element A visited." << std::endl; 91 | std::cout << "Element A data: " << element->getData() << std::endl; 92 | } 93 | 94 | void ConcreteVistor2::vistorElementB(ConcreteElementB *const element) { 95 | std::cout << "Concrete Vistor 2 : Element B visited." << std::endl; 96 | std::cout << "Element B data: " << element->getData() << std::endl; 97 | } 98 | 99 | int main() { 100 | ConcreteElementA elementA("Hello"); 101 | ConcreteElementB elementB("World"); 102 | 103 | ConcreteVistor1 vistor1; 104 | ConcreteVistor2 vistor2; 105 | 106 | elementA.accept(vistor1); 107 | elementA.accept(vistor2); 108 | 109 | elementB.accept(vistor1); 110 | elementB.accept(vistor2); 111 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(CppDesignPatterns) 4 | 5 | set (CMAKE_CXX_STANDARD 11) 6 | 7 | set(PATTERNS 8 | CreationalPatterns/abstract-factory 9 | CreationalPatterns/builder 10 | CreationalPatterns/factory-method 11 | CreationalPatterns/prototype 12 | CreationalPatterns/singleton 13 | 14 | StructuralPatterns/adapter 15 | StructuralPatterns/bridge 16 | StructuralPatterns/proxy 17 | StructuralPatterns/composite 18 | StructuralPatterns/decorator 19 | StructuralPatterns/facade 20 | StructuralPatterns/flyweight 21 | 22 | BehaviroalPatterns/chain-of-responsibility 23 | BehaviroalPatterns/command 24 | BehaviroalPatterns/interpreter 25 | BehaviroalPatterns/iterator 26 | BehaviroalPatterns/mediator 27 | BehaviroalPatterns/memento 28 | BehaviroalPatterns/observer 29 | BehaviroalPatterns/state 30 | BehaviroalPatterns/strategy 31 | BehaviroalPatterns/template-method 32 | BehaviroalPatterns/visitor 33 | ) 34 | 35 | foreach(_dir IN ITEMS ${PATTERNS}) 36 | file(GLOB _files "${_dir}/*.cxx") 37 | message(STATUS "Pattern `${_dir}':") 38 | 39 | foreach(_file IN ITEMS ${_files}) 40 | 41 | get_filename_component(_file_name 42 | ${_file} NAME 43 | ) 44 | 45 | set(_project_name "${_file_name}") 46 | message(STATUS " ${_dir}/${_file_name} is going to be built") 47 | 48 | add_executable(${_project_name} "${_dir}/${_file_name}") 49 | endforeach() 50 | 51 | endforeach() 52 | -------------------------------------------------------------------------------- /CreationalPatterns/abstract-factory/AbstractFactoryPattern.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class AbstractProductA { 11 | public: 12 | AbstractProductA() { std::cout << "AbstractProductA" << std::endl; } 13 | virtual ~AbstractProductA() {} 14 | virtual void checkProduct() = 0; 15 | }; 16 | 17 | class AbstractProductB { 18 | public: 19 | AbstractProductB() { std::cout << "AbstractProductB" << std::endl; } 20 | virtual ~AbstractProductB() {} 21 | virtual void checkProduct() = 0; 22 | }; 23 | 24 | class ProductA1 : public AbstractProductA { 25 | public: 26 | ProductA1() { std::cout << "ProductA1" << std::endl; } 27 | ~ProductA1() {} 28 | void checkProduct() { std::cout << "ProductA1 has been created" << std::endl;} 29 | 30 | }; 31 | 32 | class ProductA2 : public AbstractProductA { 33 | public: 34 | ProductA2() { std::cout << "ProductA2" << std::endl; } 35 | ~ProductA2() {} 36 | void checkProduct() { std::cout << "ProductA2 has been created" << std::endl; } 37 | 38 | }; 39 | 40 | class ProductB1 : public AbstractProductB { 41 | public: 42 | ProductB1() { std::cout << "ProductB1" << std::endl; } 43 | ~ProductB1() {} 44 | void checkProduct() { std::cout << "ProductB1 has been created" << std::endl; } 45 | 46 | }; 47 | 48 | class ProductB2 : public AbstractProductB { 49 | public: 50 | ProductB2() { std::cout << "ProductB2" << std::endl; } 51 | ~ProductB2() {} 52 | void checkProduct() { std::cout << "ProductB2 has been created" << std::endl; } 53 | 54 | }; 55 | 56 | class AbstractFactory { 57 | public: 58 | AbstractFactory() { std::cout << "AbstractFactory" << std::endl; } 59 | virtual ~AbstractFactory() {} 60 | virtual AbstractProductA* createProductA() = 0; 61 | virtual AbstractProductB* createProductB() = 0; 62 | }; 63 | 64 | class ConcreateFactory1 : public AbstractFactory { 65 | public: 66 | ConcreateFactory1() { std::cout << "ConcreateFactory1" << std::endl; } 67 | ~ConcreateFactory1() {} 68 | AbstractProductA* createProductA() { return new ProductA1; } 69 | AbstractProductB* createProductB() { return new ProductB1; } 70 | }; 71 | 72 | class ConcreateFactory2 : public AbstractFactory { 73 | public: 74 | ConcreateFactory2() { std::cout << "ConcreateFactory2" << std::endl; } 75 | ~ConcreateFactory2() {} 76 | AbstractProductA* createProductA() { return new ProductA2; } 77 | AbstractProductB* createProductB() { return new ProductB2; } 78 | }; 79 | 80 | int main(int argc, char* argv[]) { 81 | AbstractFactory* cf1 = new ConcreateFactory1(); 82 | AbstractProductA* productA1 = cf1->createProductA(); 83 | productA1->checkProduct(); 84 | AbstractProductB* productB1 = cf1->createProductB(); 85 | productB1->checkProduct(); 86 | 87 | AbstractFactory* cf2 = new ConcreateFactory2(); 88 | AbstractProductA* productA2 = cf2->createProductA(); 89 | productA2->checkProduct(); 90 | AbstractProductB* productB2 = cf1->createProductB(); 91 | productB2->checkProduct(); 92 | 93 | } -------------------------------------------------------------------------------- /CreationalPatterns/abstract-factory/README.md: -------------------------------------------------------------------------------- 1 | ## Abstract Factory 2 | 3 | Abstract factory pattern has creational purpose and provides an interface for 4 | creating families of related or dependent objects without specifying their 5 | concrete classes. Pattern applies to object and deal with object relationships, 6 | which are more dynamic. In contrast to Factory Method, Abstract Factory pattern 7 | produces family of types that are related, ie. it has more than one method of 8 | types it produces. 9 | 10 | 11 | ### When to use 12 | 13 | * a system should be independent of how its products are created, composed, and represented 14 | * a system should be configured with one of multiple families of products 15 | * a family of related product objects is designed to be used together 16 | * you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations -------------------------------------------------------------------------------- /CreationalPatterns/builder/Builder.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Product { 12 | public: 13 | void partA(const std::string &part) { 14 | part_a = part; 15 | } 16 | void partB(const std::string &part) { 17 | part_b = part; 18 | } 19 | void partC(const std::string &part) { 20 | part_c = part; 21 | } 22 | 23 | void checkProduct() { 24 | std::cout << part_a + " " + part_b + " " + part_c + " have been created" << std::endl; 25 | } 26 | 27 | private: 28 | std::string part_a; 29 | std::string part_b; 30 | std::string part_c; 31 | }; 32 | 33 | class Builder { 34 | public: 35 | Builder() { std::cout << "Builder" << std::endl; } 36 | virtual ~Builder() {} 37 | Product getProduct() { return product; } 38 | 39 | virtual void buildPartA() = 0; 40 | virtual void buildPartB() = 0; 41 | virtual void buildPartC() = 0; 42 | 43 | protected: 44 | Product product; 45 | }; 46 | 47 | class ConcreateBuilder1 : public Builder { 48 | public: 49 | ConcreateBuilder1() { std::cout << "ConcreateBuilder1" << std::endl; } 50 | ~ConcreateBuilder1() {} 51 | 52 | void buildPartA() { 53 | product.partA("1-A"); 54 | } 55 | void buildPartB() { 56 | product.partB("1-B"); 57 | } 58 | void buildPartC() { 59 | product.partC("1-C"); 60 | } 61 | 62 | }; 63 | 64 | class ConcreateBuilder2 : public Builder { 65 | public: 66 | ConcreateBuilder2() { std::cout << "ConcreateBuilder2" << std::endl; } 67 | ~ConcreateBuilder2() {} 68 | 69 | void buildPartA() { 70 | product.partA("2-A"); 71 | } 72 | void buildPartB() { 73 | product.partB("2-B"); 74 | } 75 | void buildPartC() { 76 | product.partC("2-C"); 77 | } 78 | 79 | }; 80 | 81 | class Director { 82 | public: 83 | Director() { std::cout << "Director" << std::endl; } 84 | ~Director() { 85 | if (builder) { 86 | delete builder; 87 | } 88 | } 89 | 90 | void setBuilder(Builder *b) { 91 | if (builder) { 92 | delete builder; 93 | } 94 | builder = b; 95 | } 96 | 97 | Product getProduct() { return builder->getProduct(); } 98 | 99 | void construct() { 100 | builder->buildPartA(); 101 | builder->buildPartB(); 102 | builder->buildPartC(); 103 | } 104 | 105 | private: 106 | Builder *builder = nullptr; 107 | }; 108 | 109 | int main(int argc, char* argv[]) { 110 | Director director; 111 | director.setBuilder(new ConcreateBuilder1); 112 | director.construct(); 113 | 114 | Product product1 = director.getProduct(); 115 | product1.checkProduct(); 116 | 117 | director.setBuilder(new ConcreateBuilder2); 118 | director.construct(); 119 | 120 | Product product2 = director.getProduct(); 121 | product1.checkProduct(); 122 | } -------------------------------------------------------------------------------- /CreationalPatterns/builder/README.md: -------------------------------------------------------------------------------- 1 | ## Builder 2 | 3 | Builder pattern has creational purpose and separates the construction of a complex object 4 | from its representation so that the same construction process can create different 5 | representations. It is object pattern, ie. relationships can be changed at run-time 6 | and are more dynamic. Often is used for building composite structures but constructing 7 | objects requires more domain knowledge of the client than using a Factory. 8 | 9 | ### When to use 10 | 11 | * the algorithm for creating a object should be independent of the parts and how they're assembled 12 | * the construction process must allow different representations for the object that's constructed -------------------------------------------------------------------------------- /CreationalPatterns/factory-method/FactoryMethod.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Product { 12 | public: 13 | Product() { std::cout << "Product" << std::endl; } 14 | virtual ~Product() {} 15 | 16 | virtual void checkProduct() = 0; 17 | }; 18 | 19 | class ConcreateProductA : public Product { 20 | public: 21 | ConcreateProductA() { std::cout << "ConcreateProductA" << std::endl; } 22 | ~ConcreateProductA() {} 23 | 24 | void checkProduct() { std::cout << "ProductA has been created" << std::endl; } 25 | }; 26 | 27 | class ConcreateProductB : public Product { 28 | public: 29 | ConcreateProductB() { std::cout << "ConcreateProductB" << std::endl; } 30 | ~ConcreateProductB() {} 31 | 32 | void checkProduct() { std::cout << "ProductB has been created" << std::endl; } 33 | }; 34 | 35 | class Creater { 36 | public: 37 | Creater() { std::cout << "Creater" << std::endl; } 38 | virtual ~Creater() {} 39 | 40 | virtual Product* createProductA() = 0; 41 | virtual Product* createProductB() = 0; 42 | }; 43 | 44 | class ConcreateCreater : public Creater { 45 | public: 46 | ConcreateCreater() { std::cout << "ConcreateCreater" << std::endl; } 47 | ~ConcreateCreater() {} 48 | 49 | Product* createProductA() { return new ConcreateProductA; } 50 | Product* createProductB() { return new ConcreateProductB; } 51 | }; 52 | 53 | int main(int argc, char* argv[]) { 54 | Creater *creater = new ConcreateCreater; 55 | 56 | Product *productA = creater->createProductA(); 57 | productA->checkProduct(); 58 | 59 | Product *productB = creater->createProductB(); 60 | productB->checkProduct(); 61 | 62 | } -------------------------------------------------------------------------------- /CreationalPatterns/factory-method/README.md: -------------------------------------------------------------------------------- 1 | ## Factory Method 2 | 3 | Define an interface for creating an object, but let subclasses decide which class to instantiate. 4 | Factory Method lets a class defer instantiation to subclasses. The pattern has creational purpose 5 | and applies to classes where deals with relationships through inheritence ie. they are static-fixed 6 | at compile time. In contrast to Abstract Factory, Factory Method contain method to produce only one 7 | type of product. 8 | 9 | ### When to use 10 | 11 | * a class cant anticipate the class of objects it must create 12 | * a class wants its subclasses to specify the objects it creates 13 | * classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate -------------------------------------------------------------------------------- /CreationalPatterns/prototype/Prototype.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Prototype { 12 | public: 13 | Prototype() { std::cout << "Prototpye" << std::endl; } 14 | virtual ~Prototype() {} 15 | 16 | virtual Prototype* clone() = 0; 17 | virtual void checkPrototype() = 0; 18 | }; 19 | 20 | class ConcreatePrototype1 : public Prototype { 21 | public: 22 | ConcreatePrototype1() { std::cout << "ConcreatePrototype1" << std::endl; } 23 | ~ConcreatePrototype1() {} 24 | 25 | Prototype* clone() { return new ConcreatePrototype1; } 26 | void checkPrototype() { std::cout << "Prototype1 has been created" << std::endl; } 27 | }; 28 | 29 | class ConcreatePrototype2 : public Prototype { 30 | public: 31 | ConcreatePrototype2() { std::cout << "ConcreatePrototype2" << std::endl; } 32 | ~ConcreatePrototype2() {} 33 | 34 | Prototype* clone() { return new ConcreatePrototype2; } 35 | void checkPrototype() { std::cout << "Prototype2 has been created" << std::endl; } 36 | }; 37 | 38 | class Client { 39 | public: 40 | Client() { std::cout << "Client" << std::endl; } 41 | ~Client() { 42 | if (prototype) { 43 | delete prototype; 44 | } 45 | } 46 | 47 | void setPrototype(Prototype *p) { 48 | if (prototype) { 49 | delete prototype; 50 | } 51 | prototype = p; 52 | } 53 | Prototype* clone() { 54 | if (!prototype) { 55 | return nullptr; 56 | } 57 | return prototype->clone(); 58 | } 59 | 60 | private: 61 | Prototype *prototype; 62 | }; 63 | 64 | int main(int argc, char* argv[]) { 65 | Client client; 66 | client.setPrototype(new ConcreatePrototype1); 67 | Prototype *p1 = client.clone(); 68 | p1->checkPrototype(); 69 | 70 | client.setPrototype(new ConcreatePrototype2); 71 | Prototype *p2 = client.clone(); 72 | p2->checkPrototype(); 73 | 74 | } -------------------------------------------------------------------------------- /CreationalPatterns/prototype/README.md: -------------------------------------------------------------------------------- 1 | ## Prototype 2 | 3 | Specify the kinds of objects to create using a prototypical instance, and create 4 | new objects by copying this prototype. Pattern has creational purpose and deals 5 | with object relationships, which are more dynamic. The pattern hides the complexities 6 | of making new instances from the client. 7 | 8 | ### When to use 9 | 10 | * when the classes to instantiate are specified at run-time 11 | * to avoid building a class hierarchy of factories that parallels the class hierarchy of products 12 | * when instances of a class can have one of only a few different combinations of state 13 | -------------------------------------------------------------------------------- /CreationalPatterns/singleton/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/CreationalPatterns/singleton/README.md -------------------------------------------------------------------------------- /CreationalPatterns/singleton/Singleton.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Singleton { 12 | public: 13 | Singleton(const Singleton&) = delete; 14 | Singleton& operator=(const Singleton&) = delete; 15 | 16 | static Singleton* instance() { 17 | if (!instance_) { 18 | instance_ = new Singleton(); 19 | } 20 | return instance_; 21 | } 22 | 23 | void checkSingleton() { std::cout << "Singleton has been created" << std::endl; } 24 | private: 25 | Singleton() { std::cout << "Singleton" << std::endl; } 26 | static Singleton* instance_; 27 | }; 28 | 29 | Singleton* Singleton::instance_ = nullptr; 30 | 31 | int main(int argc, char* argv[]) { 32 | Singleton *singleton = Singleton::instance(); 33 | singleton->checkSingleton(); 34 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2020 Junzhuo Du 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## C++ Design Patterns 2 | 3 | C++ Implementation for 23 Design Patterns 4 | 5 | #### Creational Patterns 6 | - [Abstract Factory], families of product objects 7 | ![image](./images/AbstractFactory.png) 8 | - [Builder], how a composite object gets created 9 | ![image](./images/Builder.png) 10 | - [Factory Method], subclass of object that is instantiated 11 | ![image](./images/Factory.png) 12 | - [Prototype], class of object that is instantiated 13 | ![image](images/Prototype.png) 14 | - [Singleton], the sole instance of a class 15 | ![image](./images/SingletonPattern.png) 16 | #### Structural Patterns 17 | - [Adapter], interface to an object 18 | ![image](./images/Adapter.png) 19 | - [Bridge], implementation of an object 20 | ![image](./images/Bridge.png) 21 | - [Composite], structure and composition of an object 22 | ![image](./images/Composite.png) 23 | - [Decorator], responsibilities of an object without subclassing 24 | ![image](./images/Decorator.png) 25 | - [Façade], interface to a subsystem 26 | ![image](./images/Facade.png) 27 | - [Flyweight], storage costs of objects 28 | ![image](./images/Flyweight.png) 29 | - [Proxy], how an object is accessed (its location) 30 | ![image](./images/Proxy.png) 31 | #### Behavioral Patterns 32 | - [Chain of Responsibility], object that can fulfill a request 33 | ![image](./images/ChainOfResponsibility.png) 34 | - [Command], when and how a request is fulfilled 35 | ![image](./images/Command.PNG) 36 | - [Interpreter], grammar and interpretation of a language 37 | ![image](./images/Interpreter.PNG) 38 | - [Iterator], how an aggregate's elements are accessed 39 | ![image](./images/Iterator.png) 40 | - [Mediator], how and which objects interact with each other 41 | ![image](./images/Mediator.PNG) 42 | - [Memento], what private information is stored outside an object, and when 43 | ![image](./images/Memento.PNG) 44 | - [Observer], how the dependent objects stay up to date 45 | ![image](./images/Observer.PNG) 46 | - [State], states of an object 47 | ![image](./images/State.PNG) 48 | - [Strategy], an algorithm 49 | ![image](./images/Strategy.PNG) 50 | - [Template Method], steps of an algorithm 51 | ![image](./images/TemplateMethod.png) 52 | - [Visitor], operations that can be applied to objects without changing their classes 53 | ![image](./images/Visitor.PNG) 54 | 55 | ### References 56 | Design patterns in this repository are based on 57 | 58 | * [Design Patterns by The "Gang of Four"] 59 | * [Design Patterns in C++] 60 | * [Wikipedia] 61 | * [Design Patterns] 62 | 63 | [Design Patterns by The "Gang of Four"]: https://en.wikipedia.org/wiki/Design_Patterns 64 | [Design Patterns in C++]: https://github.com/JakubVojvoda/design-patterns-cpp 65 | [Wikipedia]: https://en.wikipedia.org/wiki/Software_design_pattern 66 | [Design Patterns]: https://refactoring.guru/design-patterns 67 | 68 | [Abstract Factory]: https://github.com/Junzhuodu/design-patterns/tree/master/CreationalPatterns/abstract-factory 69 | [Builder]: https://github.com/Junzhuodu/design-patterns/tree/master/CreationalPatterns/builder 70 | [Factory Method]: https://github.com/Junzhuodu/design-patterns/tree/master/CreationalPatterns/factory-method 71 | [Prototype]: https://github.com/Junzhuodu/design-patterns/tree/master/CreationalPatterns/prototype 72 | [Singleton]: https://github.com/Junzhuodu/design-patterns/tree/master/CreationalPatterns/singleton 73 | 74 | [Adapter]: https://github.com/Junzhuodu/design-patterns/tree/master/StructuralPatterns/adapter 75 | [Bridge]: https://github.com/Junzhuodu/design-patterns/tree/master/StructuralPatterns/bridge 76 | [Composite]: https://github.com/Junzhuodu/design-patterns/tree/master/StructuralPatterns/composite 77 | [Decorator]: https://github.com/Junzhuodu/design-patterns/tree/master/StructuralPatterns/decorator 78 | [Façade]: https://github.com/Junzhuodu/design-patterns/tree/master/StructuralPatterns/facade 79 | [Flyweight]: https://github.com/Junzhuodu/design-patterns/tree/master/StructuralPatterns/flyweight 80 | [Proxy]: https://github.com/Junzhuodu/design-patterns/tree/master/StructuralPatterns/proxy 81 | 82 | [Chain of Responsibility]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/chain-of-responsibility 83 | [Command]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/command 84 | [Interpreter]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/interpreter 85 | [Iterator]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/iterator 86 | [Mediator]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/mediator 87 | [Memento]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/memento 88 | [Observer]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/observer 89 | [State]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/state 90 | [Strategy]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/strategy 91 | [Template Method]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/template-method 92 | [Visitor]: https://github.com/Junzhuodu/design-patterns/tree/master/BehaviroalPatterns/visitor 93 | -------------------------------------------------------------------------------- /StructuralPatterns/adapter/ClassAdapter.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Target { 12 | public: 13 | Target() { std::cout << "Target" << std::endl; } 14 | virtual ~Target() {}; 15 | 16 | virtual void request() = 0; 17 | }; 18 | 19 | class Adaptee { 20 | public: 21 | Adaptee() { std::cout << "Adaptee" << std::endl; } 22 | ~Adaptee() {} 23 | 24 | void specificRequest() { std::cout << "This is specific request" << std::endl; } 25 | }; 26 | 27 | class Adapter : public Target, private Adaptee { 28 | public: 29 | Adapter() { std::cout << "Adapter" << std::endl; } 30 | ~Adapter() {} 31 | 32 | void request() { 33 | specificRequest(); 34 | std::cout << "This is request" << std::endl; 35 | } 36 | }; 37 | 38 | int main() { 39 | Target *t = new Adapter(); 40 | t->request(); 41 | } -------------------------------------------------------------------------------- /StructuralPatterns/adapter/ObjectAdapter.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Target { 12 | public: 13 | Target() { std::cout << "Target" << std::endl; } 14 | virtual ~Target() {}; 15 | 16 | virtual void request() = 0; 17 | }; 18 | 19 | class Adaptee { 20 | public: 21 | Adaptee() { std::cout << "Adaptee" << std::endl; } 22 | ~Adaptee() {} 23 | 24 | void specificRequest() { std::cout << "This is specific request" << std::endl; } 25 | }; 26 | 27 | class Adapter : public Target { 28 | public: 29 | Adapter() { 30 | adaptee = new Adaptee(); 31 | std::cout << "Adapter" << std::endl; 32 | } 33 | ~Adapter() { 34 | delete adaptee; 35 | } 36 | 37 | void request() { 38 | adaptee->specificRequest(); 39 | std::cout << "This is request" << std::endl; 40 | } 41 | 42 | private: 43 | Adaptee *adaptee = nullptr; 44 | }; 45 | 46 | int main() { 47 | Target *t = new Adapter(); 48 | t->request(); 49 | } -------------------------------------------------------------------------------- /StructuralPatterns/adapter/README.md: -------------------------------------------------------------------------------- 1 | ## Adapter 2 | 3 | Convert the interface of a class into another interface the clients expect. 4 | Adapter lets classes work together that couldn't otherwise because of 5 | incompatible interfaces, ie. allows to use a client with an incompatible 6 | interface by an Adapter that does the conversion. Adapter has structural purpose 7 | and can be applied on classes and also on object. A class adapter uses multiple 8 | inheritance to adapt one interface to another and the object adapter uses object 9 | composition to combine classes with different interfaces. 10 | 11 | ### When to use 12 | 13 | * you want to use an existing class, and its interface does not match the one you need 14 | * you want to create a reusable class that cooperates with classes that don't necessarily have compatible interfaces 15 | 16 | -------------------------------------------------------------------------------- /StructuralPatterns/bridge/Bridge.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Implementor { 12 | public: 13 | Implementor() { std::cout << "Implementor" << std::endl; } 14 | virtual ~Implementor() {} 15 | 16 | virtual void operationImp() = 0; 17 | }; 18 | 19 | class ConcreateImplementorA : public Implementor { 20 | public: 21 | ConcreateImplementorA() { std::cout << "ConcreateImplementorA" << std::endl; } 22 | ~ConcreateImplementorA() {} 23 | 24 | void operationImp() { std::cout << "This is operationImp from ConcreateImplementorA" << std::endl; } 25 | }; 26 | 27 | class ConcreateImplementorB : public Implementor { 28 | public: 29 | ConcreateImplementorB() { std::cout << "ConcreateImplementorB" << std::endl; } 30 | ~ConcreateImplementorB() {} 31 | 32 | void operationImp() { std::cout << "This is operationImp from ConcreateImplementorB" << std::endl; } 33 | }; 34 | 35 | class Abstraction { 36 | public: 37 | Abstraction() { std::cout << "Abstraction" << std::endl; } 38 | virtual ~Abstraction() {} 39 | 40 | virtual void operation() = 0; 41 | }; 42 | 43 | class RefinedAbstraction : public Abstraction { 44 | public: 45 | ~RefinedAbstraction() {} 46 | RefinedAbstraction(Implementor *ip) : implementor(ip) { 47 | std::cout << "RefinedAbstraction" << std::endl; 48 | } 49 | 50 | void operation() { 51 | implementor->operationImp(); 52 | } 53 | 54 | private: 55 | Implementor *implementor; 56 | }; 57 | 58 | int main() { 59 | Implementor *imp1 = new ConcreateImplementorA(); 60 | Abstraction *abs1 = new RefinedAbstraction(imp1); 61 | abs1->operation(); 62 | 63 | Implementor *imp2 = new ConcreateImplementorB(); 64 | Abstraction *abs2 = new RefinedAbstraction(imp2); 65 | abs2->operation(); 66 | } -------------------------------------------------------------------------------- /StructuralPatterns/bridge/README.md: -------------------------------------------------------------------------------- 1 | ## Bridge 2 | 3 | Decouple an abstraction from its implementation so that the two can vary independently. 4 | Bridge pattern has structural purpose and applies to objects, so it deals with the composition of objects. 5 | 6 | ### When to use 7 | 8 | * you want to avoid a permanent binding between an abstraction and its implementation 9 | * both the abstractions and their implementations should be extensible by subclassing 10 | * changes in the implementation of an abstraction should have no impact on clients 11 | * you want to hide the implementation of an abstraction completely from clients 12 | -------------------------------------------------------------------------------- /StructuralPatterns/composite/Composite.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | class Component { 13 | public: 14 | Component() { std::cout << "Component" << std::endl; } 15 | virtual ~Component() {} 16 | 17 | virtual void operation() = 0; 18 | 19 | virtual void add(Component *) {}; 20 | virtual void remove(Component *) {}; 21 | virtual Component* getChild(int) { return nullptr; }; 22 | }; 23 | 24 | class Leaf : public Component { 25 | public: 26 | Leaf(int id) : id_(id) { std::cout << "Leaf" << std::endl; } 27 | ~Leaf() {} 28 | 29 | void operation() { std::cout << "This is operation from Leaf: " << id_ << std::endl; } 30 | 31 | private: 32 | int id_; 33 | }; 34 | 35 | class Composite : public Component { 36 | public: 37 | Composite() { std::cout << "Composite" << std::endl; } 38 | ~Composite() { 39 | for (unsigned int i = 0; i < children_.size(); ++i) { 40 | delete children_[i]; 41 | } 42 | } 43 | 44 | void operation() { 45 | std::cout << "size of children: " << children_.size() << std::endl; 46 | for (unsigned int i = 0; i < children_.size(); ++i) { 47 | children_[i]->operation(); 48 | } 49 | } 50 | 51 | void add(Component *c) { 52 | children_.push_back(c); 53 | } 54 | 55 | void remove(Component *c) { 56 | for (auto iter = children_.begin(); iter != children_.end(); ++iter) { 57 | if (*iter == c) { 58 | children_.erase(iter); 59 | } 60 | } 61 | } 62 | 63 | Component* getChild(unsigned int idx) { 64 | return idx < children_.size() ? children_[idx] : nullptr; 65 | } 66 | 67 | private: 68 | std::vector children_; 69 | }; 70 | 71 | int main() { 72 | Composite composite; 73 | for (unsigned int i = 0; i < 3; ++i) { 74 | composite.add(new Leaf(i)); 75 | } 76 | 77 | composite.add(new Composite); 78 | 79 | composite.remove(0); 80 | composite.operation(); 81 | 82 | Component *component1 = composite.getChild(0); 83 | component1->operation(); 84 | 85 | Component *component2 = composite.getChild(3); 86 | component2->operation(); 87 | 88 | } -------------------------------------------------------------------------------- /StructuralPatterns/composite/README.md: -------------------------------------------------------------------------------- 1 | ## Composite 2 | 3 | Compose objects into tree structures to represent part-whole hierarchies. 4 | Composite lets clients treat individual objects and compositions of objects uniformly. 5 | The pattern has structural purpose and applies to objects. 6 | 7 | ### When to use 8 | 9 | * you want to represent part-whole hierarchies of objects 10 | * you want clients to be able to ignore the difference between compositions of objects and individual objects -------------------------------------------------------------------------------- /StructuralPatterns/decorator/Decorator.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | class Component { 12 | public: 13 | virtual ~Component() {} 14 | 15 | virtual void operation() = 0; 16 | }; 17 | 18 | class ConcreteComponent : public Component { 19 | public: 20 | ~ConcreteComponent() {} 21 | 22 | void operation() { 23 | std::cout << "Concrete Component operation" << std::endl; 24 | } 25 | }; 26 | 27 | class Decorator : public Component { 28 | public: 29 | ~Decorator() {} 30 | 31 | Decorator(Component *c) : component_(c) {} 32 | 33 | virtual void operation() { 34 | component_->operation(); 35 | } 36 | private: 37 | Component *component_; 38 | }; 39 | 40 | class ConcreteDecoratorA : public Decorator { 41 | public: 42 | ConcreteDecoratorA(Component *c) : Decorator(c) {} 43 | 44 | void operation() { 45 | Decorator::operation(); 46 | std::cout << "AddedBehavior for ConcreteDecoratorA" << std::endl; 47 | } 48 | }; 49 | 50 | class ConcreteDecoratorB : public Decorator { 51 | public: 52 | ConcreteDecoratorB(Component *c) : Decorator(c) {} 53 | 54 | void operation() { 55 | Decorator::operation(); 56 | std::cout << "AddedBehavior for ConcreteDecoratorB" << std::endl; 57 | } 58 | }; 59 | 60 | int main() { 61 | Component *cc = new ConcreteComponent(); 62 | ConcreteDecoratorA *cda = new ConcreteDecoratorA(cc); 63 | ConcreteDecoratorB *cdb = new ConcreteDecoratorB(cc); 64 | 65 | cda->operation(); 66 | cdb->operation(); 67 | 68 | } -------------------------------------------------------------------------------- /StructuralPatterns/decorator/README.md: -------------------------------------------------------------------------------- 1 | ## Decorator 2 | 3 | Attach additional responsibilities to an object dynamically. Decorators 4 | provide a flexible alternative to subclassing for extending functionality. 5 | The pattern has structural purpose and applies to objects. 6 | 7 | ### When to use 8 | 9 | * to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects 10 | * for responsibilities that can be withdrawn 11 | * when extension by subclassing is impractical -------------------------------------------------------------------------------- /StructuralPatterns/facade/Facade.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class SubSystem1 { 11 | public: 12 | void suboperation() { 13 | std::cout << "SubSystem1 operation" << std::endl; 14 | } 15 | }; 16 | 17 | class SubSystem2 { 18 | public: 19 | void suboperation() { 20 | std::cout << "SubSystem2 operation" << std::endl; 21 | } 22 | }; 23 | 24 | class Facade { 25 | public: 26 | Facade() { 27 | std::cout << "Facade" << std::endl; 28 | subsystem1 = new SubSystem1(); 29 | subsystem2 = new SubSystem2(); 30 | } 31 | 32 | ~Facade() { 33 | if (subsystem1) { 34 | delete subsystem1; 35 | } 36 | if (subsystem2) { 37 | delete subsystem2; 38 | } 39 | } 40 | 41 | void operationWrapper() { 42 | subsystem1->suboperation(); 43 | subsystem2->suboperation(); 44 | } 45 | 46 | private: 47 | SubSystem1 *subsystem1; 48 | SubSystem2 *subsystem2; 49 | }; 50 | 51 | int main() { 52 | Facade facade; 53 | facade.operationWrapper(); 54 | } -------------------------------------------------------------------------------- /StructuralPatterns/facade/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/StructuralPatterns/facade/README.md -------------------------------------------------------------------------------- /StructuralPatterns/flyweight/Flyweight.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | class Flyweight { 13 | public: 14 | virtual ~Flyweight() {} 15 | 16 | virtual void operation(const std::string& extrinsicState) = 0; 17 | }; 18 | 19 | class ConcreteFlyweight : public Flyweight { 20 | public: 21 | ConcreteFlyweight(const std::string& intrinsicState) : 22 | intrinsicState_(intrinsicState) { 23 | std::cout << "ConcreteFlyweight + intrinsicState: " << intrinsicState_ << std::endl; 24 | } 25 | ~ConcreteFlyweight() {} 26 | 27 | void operation(const std::string& extrinsicState) { 28 | std::cout << "ConcreteFlyweight operation extrinsicState: " << extrinsicState << std::endl; 29 | } 30 | 31 | private: 32 | std::string intrinsicState_; 33 | }; 34 | 35 | class UnsharedConcreteFlyweight : public Flyweight { 36 | public: 37 | UnsharedConcreteFlyweight(const std::string& allState) : allState_(allState) { 38 | std::cout << "UnsharedConcreteFlyweight allState: " << allState_ << std::endl; 39 | } 40 | void operation(const std::string& extrinsicState) { 41 | std::cout << "UnsharedConcreteFlyweight operation extrinsicState: " << extrinsicState << std::endl; 42 | } 43 | private: 44 | std::string allState_; 45 | }; 46 | 47 | class FlyweightFactory { 48 | public: 49 | ~FlyweightFactory() { 50 | for (auto it = flys.begin(); it != flys.end(); ++it) { 51 | delete it->second; 52 | } 53 | flys.clear(); 54 | } 55 | 56 | Flyweight *getFlyweight(const std::string& key) { 57 | if (flys.find(key) != flys.end()) { 58 | std::cout << "existed flyweight" << std::endl; 59 | 60 | return flys[key]; 61 | } 62 | Flyweight *fly = new ConcreteFlyweight(key); 63 | flys.insert(std::make_pair(key, fly)); 64 | std::cout << "new flyweight" << std::endl; 65 | 66 | return fly; 67 | } 68 | 69 | private: 70 | std::unordered_map flys; 71 | }; 72 | 73 | int main() { 74 | FlyweightFactory *factory = new FlyweightFactory(); 75 | factory->getFlyweight("Hello")->operation("world"); 76 | factory->getFlyweight("Hello")->operation("World"); 77 | factory->getFlyweight("hello")->operation("world"); 78 | 79 | Flyweight* unsharedfly = new UnsharedConcreteFlyweight("what's up"); 80 | unsharedfly->operation("helloworld"); 81 | } 82 | 83 | -------------------------------------------------------------------------------- /StructuralPatterns/flyweight/README.md: -------------------------------------------------------------------------------- 1 | ## Flyweight 2 | 3 | Flyweight pattern has has structural purpose, applies to objects and uses sharing to support 4 | large numbers of fine-grained objects efficiently. The pattern can be used to reduce 5 | memory usage when you need to create a large number of similar objects. 6 | 7 | ### When to use 8 | 9 | * when one instance of a class can be used to provide many "virtual instances" 10 | * when all of the following are true 11 | * an application uses a large number of objects 12 | * storage costs are high because of the sheer quantity of objects 13 | * most object state can be made extrinsic 14 | * many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed 15 | * the application doesn't depend on object identity -------------------------------------------------------------------------------- /StructuralPatterns/proxy/Proxy.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * C++ Design Patterns: 3 | * Author: Junzhuo Du [github.com/Junzhuodu] 4 | * 2020 5 | * 6 | */ 7 | 8 | #include 9 | 10 | class Subject { 11 | public: 12 | virtual ~Subject() {} 13 | 14 | virtual void request() = 0; 15 | }; 16 | 17 | class RealSubject : public Subject { 18 | public: 19 | void request() { 20 | std::cout << "RealSubject Request" << std::endl; 21 | } 22 | }; 23 | 24 | class Proxy : public Subject 25 | { 26 | public: 27 | Proxy() 28 | { 29 | subject = new RealSubject(); 30 | } 31 | 32 | ~Proxy() 33 | { 34 | delete subject; 35 | } 36 | 37 | void request() 38 | { 39 | subject->request(); 40 | } 41 | 42 | private: 43 | RealSubject *subject; 44 | }; 45 | 46 | 47 | int main() 48 | { 49 | Proxy *proxy = new Proxy(); 50 | proxy->request(); 51 | 52 | delete proxy; 53 | return 0; 54 | } -------------------------------------------------------------------------------- /StructuralPatterns/proxy/README.md: -------------------------------------------------------------------------------- 1 | ## Proxy 2 | 3 | Proxy pattern provides a surrogate or placeholder for another object to control access to it. 4 | The pattern has structural purpose and applies to objects. 5 | 6 | ### When to use 7 | 8 | * whenever there is a need for a more versatile or sophisticated reference to an object than a simple pointer 9 | -------------------------------------------------------------------------------- /images/AbstractFactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/AbstractFactory.png -------------------------------------------------------------------------------- /images/Adapter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Adapter.png -------------------------------------------------------------------------------- /images/Bridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Bridge.png -------------------------------------------------------------------------------- /images/Builder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Builder.png -------------------------------------------------------------------------------- /images/ChainOfResponsibility.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/ChainOfResponsibility.png -------------------------------------------------------------------------------- /images/Command.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Command.PNG -------------------------------------------------------------------------------- /images/Composite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Composite.png -------------------------------------------------------------------------------- /images/Decorator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Decorator.png -------------------------------------------------------------------------------- /images/Facade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Facade.png -------------------------------------------------------------------------------- /images/Factory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Factory.png -------------------------------------------------------------------------------- /images/Flyweight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Flyweight.png -------------------------------------------------------------------------------- /images/Interpreter.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Interpreter.PNG -------------------------------------------------------------------------------- /images/Iterator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Iterator.png -------------------------------------------------------------------------------- /images/Mediator.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Mediator.PNG -------------------------------------------------------------------------------- /images/Memento.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Memento.PNG -------------------------------------------------------------------------------- /images/Observer.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Observer.PNG -------------------------------------------------------------------------------- /images/Prototype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Prototype.png -------------------------------------------------------------------------------- /images/Proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Proxy.png -------------------------------------------------------------------------------- /images/SingletonPattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/SingletonPattern.png -------------------------------------------------------------------------------- /images/State.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/State.PNG -------------------------------------------------------------------------------- /images/Strategy.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Strategy.PNG -------------------------------------------------------------------------------- /images/TemplateMethod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/TemplateMethod.png -------------------------------------------------------------------------------- /images/Visitor.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Junzhuodu/design-patterns/1c486afbb91ef824fe9ace8b604062c8fdb06806/images/Visitor.PNG --------------------------------------------------------------------------------