├── Decorator-Pattern ├── Makefile ├── README.md ├── Espresso.hpp ├── Beverage.hpp ├── HouseBlend.hpp ├── CondimentDecorator.hpp ├── Mocha.hpp └── main.cpp ├── Command-Pattern ├── Makefile ├── Command.hpp ├── README.md ├── SimpleRemoteControl.hpp ├── GarageDoorOpen.hpp ├── LightOnCommand.hpp └── main.cpp ├── Factory-Pattern ├── Makefile ├── README.md ├── main.cpp ├── NYStyleCheesePizza.hpp ├── ChicagoStyleCheesePizza.hpp ├── ChicagoStylePepperoniPizza.hpp ├── PizzaStore.hpp ├── NYPizzaStore.hpp ├── NYStylePepperoniPizza.hpp ├── ChicagoPizzaStore.hpp └── Pizza.hpp ├── Observer-Pattern ├── Makefile ├── README.md ├── DisplayElement.hpp ├── Observer.hpp ├── Subject.hpp ├── main.cpp ├── WeatherData.hpp └── CurrentConditionsDisplay.hpp ├── Strategy-Pattern ├── Makefile ├── DecoyDuck.hpp ├── README.md ├── FlyBehavior.hpp ├── RubberDuck.hpp ├── MallardDuck.hpp ├── RedHeadDuck.hpp ├── QuackBehavior.hpp ├── Quack.hpp ├── Squeak.hpp ├── FlyNoWay.hpp ├── MuteQuack.hpp ├── FlyWithWings.hpp ├── DecoyDuck.cpp ├── RubberDuck.cpp ├── MallardDuck.cpp ├── RedHeadDuck.cpp ├── Duck.hpp └── main.cpp ├── Template-Pattern ├── Makefile ├── README.md ├── main.cpp ├── Tea.hpp ├── Coffee.hpp └── CaffeineBeverage.hpp ├── Bridge ├── bridge1.cpp ├── bridge2.cpp └── README.md ├── Prototype ├── Client.cpp ├── Prototype.cpp ├── README.md └── ConcretePrototype.cpp ├── Observer ├── MainForm2.cpp ├── FileSplitter1.cpp ├── FileSplitter2.cpp ├── MainForm1.cpp └── README.md ├── Strategy ├── strategy1.cpp ├── strategy2.cpp └── README.md ├── Factory Method ├── MainForm1.cpp ├── MainForm2.cpp ├── ISplitterFactory.cpp ├── FileSplitter1.cpp ├── README.md └── FileSplitter2.cpp ├── Template Method ├── template1_app.cpp ├── template1_lib.cpp ├── template2_app.cpp ├── template2_lib.cpp ├── Makefile └── README.md ├── Adapter ├── README.md └── Adapter.cpp ├── Proxy ├── README.md ├── client.cpp └── proxy.cpp ├── Memento ├── README.md └── memento.cpp ├── State ├── README.md ├── state1.cpp └── state2.cpp ├── Chain of Resposibility ├── README.md └── ChainofResposibility.cpp ├── Mediator └── README.md ├── Command ├── README.md └── Command.cpp ├── Singleton ├── README.md └── Singleton.cpp ├── Iterator ├── README.md └── Iterator.cpp ├── Facade └── README.md ├── Abstract Factory ├── README.md ├── EmployeeDAO1.cpp ├── EmployeeDAO3.cpp └── EmployeeDAO2.cpp ├── Flyweight ├── README.md └── flyweight.cpp ├── Interpreter ├── README.md └── main.cpp ├── Builder ├── README.md └── builder.cpp ├── Composite ├── README.md └── composite.cpp ├── Visitor ├── README.md ├── Visitor2.cpp └── Visitor1.cpp ├── Decorator ├── README.md ├── decorator2.cpp ├── decorator3.cpp └── decorator1.cpp └── README.md /Decorator-Pattern/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -g -Wall -o main main.cpp 3 | 4 | rm: 5 | main -------------------------------------------------------------------------------- /Command-Pattern/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -g -Wall main.cpp -o main 3 | 4 | clean: 5 | rm main 6 | -------------------------------------------------------------------------------- /Factory-Pattern/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -g -Wall main.cpp -o main 3 | 4 | clean: 5 | rm main 6 | -------------------------------------------------------------------------------- /Observer-Pattern/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -g -Wall main.cpp -o main 3 | 4 | clean: 5 | rm main 6 | -------------------------------------------------------------------------------- /Strategy-Pattern/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -g -Wall ./*.cpp -o main 3 | 4 | clean: 5 | rm main 6 | -------------------------------------------------------------------------------- /Template-Pattern/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -g -Wall main.cpp -o main 3 | 4 | clean: 5 | rm main 6 | -------------------------------------------------------------------------------- /Bridge/bridge1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Bridge/bridge1.cpp -------------------------------------------------------------------------------- /Bridge/bridge2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Bridge/bridge2.cpp -------------------------------------------------------------------------------- /Prototype/Client.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Prototype/Client.cpp -------------------------------------------------------------------------------- /Observer/MainForm2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Observer/MainForm2.cpp -------------------------------------------------------------------------------- /Strategy/strategy1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Strategy/strategy1.cpp -------------------------------------------------------------------------------- /Strategy/strategy2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Strategy/strategy2.cpp -------------------------------------------------------------------------------- /Factory Method/MainForm1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Factory Method/MainForm1.cpp -------------------------------------------------------------------------------- /Factory Method/MainForm2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Factory Method/MainForm2.cpp -------------------------------------------------------------------------------- /Observer/FileSplitter1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Observer/FileSplitter1.cpp -------------------------------------------------------------------------------- /Observer/FileSplitter2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Observer/FileSplitter2.cpp -------------------------------------------------------------------------------- /Template Method/template1_app.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Template Method/template1_app.cpp -------------------------------------------------------------------------------- /Template Method/template1_lib.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Template Method/template1_lib.cpp -------------------------------------------------------------------------------- /Template Method/template2_app.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Template Method/template2_app.cpp -------------------------------------------------------------------------------- /Template Method/template2_lib.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liu-jianhao/Cpp-Design-Patterns/HEAD/Template Method/template2_lib.cpp -------------------------------------------------------------------------------- /Template Method/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ -g -Wall -o template1 template1_lib.cpp template1_app.cpp 3 | g++ -g -Wall -o template2 template2_lib.cpp template2_app.cpp 4 | 5 | clean: 6 | rm -rf template1 template2 -------------------------------------------------------------------------------- /Command-Pattern/Command.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COMMAND_HPP 2 | #define COMMAND_HPP 3 | 4 | class Command { 5 | public: 6 | virtual void execute() = 0; 7 | 8 | virtual ~Command() = default; 9 | }; 10 | 11 | #endif -------------------------------------------------------------------------------- /Command-Pattern/README.md: -------------------------------------------------------------------------------- 1 | ## 命令模式 2 | 3 | ![](https://img-blog.csdnimg.cn/20190616212348873.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlc3Ricm9va2xpdQ==,size_16,color_FFFFFF,t_70) -------------------------------------------------------------------------------- /Factory-Pattern/README.md: -------------------------------------------------------------------------------- 1 | ## 工厂模式 2 | 3 | ![](https://img-blog.csdnimg.cn/20190623171420456.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlc3Ricm9va2xpdQ==,size_16,color_FFFFFF,t_70) -------------------------------------------------------------------------------- /Observer-Pattern/README.md: -------------------------------------------------------------------------------- 1 | ## 观察者模式 2 | 3 | ![](https://img-blog.csdnimg.cn/20190601170922608.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlc3Ricm9va2xpdQ==,size_16,color_FFFFFF,t_70) 4 | -------------------------------------------------------------------------------- /Strategy-Pattern/DecoyDuck.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DECOYDUCK_HPP 2 | #define DECOYDUCK_HPP 3 | 4 | #include "Duck.hpp" 5 | 6 | class DecoyDuck : public Duck { 7 | public: 8 | DecoyDuck(); 9 | 10 | void display(); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /Strategy-Pattern/README.md: -------------------------------------------------------------------------------- 1 | ## 策略模式 2 | 3 | ![](https://img-blog.csdnimg.cn/20190527222242725.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlc3Ricm9va2xpdQ==,size_16,color_FFFFFF,t_70) 4 | -------------------------------------------------------------------------------- /Template-Pattern/README.md: -------------------------------------------------------------------------------- 1 | ## 模板方法模式 2 | 3 | ![](https://img-blog.csdnimg.cn/20190619233700891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlc3Ricm9va2xpdQ==,size_16,color_FFFFFF,t_70) -------------------------------------------------------------------------------- /Decorator-Pattern/README.md: -------------------------------------------------------------------------------- 1 | ## 装饰者模式 2 | 3 | ![](https://img-blog.csdnimg.cn/20190610235715849.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlc3Ricm9va2xpdQ==,size_16,color_FFFFFF,t_70) 4 | -------------------------------------------------------------------------------- /Observer-Pattern/DisplayElement.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DISPLAYELEMENT_HPP 2 | #define DISPLAYELEMENT_HPP 3 | 4 | class DisplayElement { 5 | public: 6 | virtual ~DisplayElement() = default; 7 | virtual void display() = 0; 8 | }; 9 | 10 | #endif -------------------------------------------------------------------------------- /Prototype/Prototype.cpp: -------------------------------------------------------------------------------- 1 | 2 | //抽象类 3 | class ISplitter{ 4 | public: 5 | virtual void split()=0; 6 | virtual ISplitter* clone()=0; //通过克隆自己来创建对象 7 | 8 | virtual ~ISplitter(){} 9 | 10 | }; 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Strategy-Pattern/FlyBehavior.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLYBEHAVIOR_HPP 2 | #define FLYBEHAVIOR_HPP 3 | 4 | // 接口类 5 | class FlyBehavior { 6 | public: 7 | virtual void fly() = 0; 8 | 9 | virtual ~FlyBehavior() = default; 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /Strategy-Pattern/RubberDuck.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RUBBERDUCK_HPP 2 | #define RUBBERDUCK_HPP 3 | 4 | #include "Duck.hpp" 5 | 6 | class RubberDuck : public Duck { 7 | public: 8 | RubberDuck(); 9 | 10 | void display(); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /Strategy-Pattern/MallardDuck.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MALLARDDUCK_HPP 2 | #define MALLARDDUCK_HPP 3 | 4 | #include "Duck.hpp" 5 | 6 | class MallardDuck : public Duck { 7 | public: 8 | MallardDuck(); 9 | 10 | void display(); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /Strategy-Pattern/RedHeadDuck.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REDHEADDUCK_HPP 2 | #define REDHEADDUCK_HPP 3 | 4 | #include "Duck.hpp" 5 | 6 | class RedHeadDuck : public Duck { 7 | public: 8 | RedHeadDuck(); 9 | 10 | void display(); 11 | }; 12 | 13 | #endif -------------------------------------------------------------------------------- /Observer-Pattern/Observer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef OBSERVER_HPP 2 | #define OBSERVER_HPP 3 | 4 | class Observer { 5 | public: 6 | virtual ~Observer() = default; 7 | virtual void update(float temp, float humidity, float pressure) = 0; 8 | }; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Strategy-Pattern/QuackBehavior.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QUACKBEHAVIOR_HPP 2 | #define QUACKBEHAVIOR_HPP 3 | 4 | // 接口类 5 | class QuackBehavior { 6 | public: 7 | virtual void quack() = 0; 8 | 9 | virtual ~QuackBehavior() = default; 10 | }; 11 | 12 | #endif -------------------------------------------------------------------------------- /Adapter/README.md: -------------------------------------------------------------------------------- 1 | # Adapter 2 | 3 | ## 动机(Motivation) 4 | + 由于应用环境的变化,常常需要将”一些现存的对象“放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足。 5 | + 如何应对这些”迁移的变化“? 6 | 7 | ## 模式定义 8 | 将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + 在遗留代码复用、类库迁移等方面有用 13 | -------------------------------------------------------------------------------- /Strategy-Pattern/Quack.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QUACK_HPP 2 | #define QUACK_HPP 3 | 4 | #include "QuackBehavior.hpp" 5 | 6 | #include 7 | 8 | class Quack : public QuackBehavior { 9 | public: 10 | void quack() { 11 | std::cout << "Quack" << std::endl; 12 | } 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /Strategy-Pattern/Squeak.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SQUEAK_HPP 2 | #define SQUEAK_HPP 3 | 4 | #include "QuackBehavior.hpp" 5 | 6 | #include 7 | 8 | class Squeak : public QuackBehavior { 9 | public: 10 | void quack() { 11 | std::cout << "Squeak" << std::endl; 12 | } 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /Strategy-Pattern/FlyNoWay.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLYNOWAY_HPP 2 | #define FLYNOWAY_HPP 3 | 4 | #include "FlyBehavior.hpp" 5 | 6 | #include 7 | 8 | class FlyNoWay : public FlyBehavior { 9 | public: 10 | void fly() { 11 | std::cout << "I can't fly" << std::endl; 12 | } 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /Strategy-Pattern/MuteQuack.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MUTEQUACK_HPP 2 | #define MUTEQUACK_HPP 3 | 4 | #include "QuackBehavior.hpp" 5 | 6 | #include 7 | 8 | class MuteQuack : public QuackBehavior { 9 | public: 10 | void quack() { 11 | std::cout << "Mute Quack" << std::endl; 12 | } 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /Factory Method/ISplitterFactory.cpp: -------------------------------------------------------------------------------- 1 | 2 | //抽象类 3 | class ISplitter{ 4 | public: 5 | virtual void split()=0; 6 | virtual ~ISplitter(){} 7 | }; 8 | 9 | 10 | //工厂基类 11 | class SplitterFactory{ 12 | public: 13 | virtual ISplitter* CreateSplitter()=0; 14 | virtual ~SplitterFactory(){} 15 | }; 16 | -------------------------------------------------------------------------------- /Strategy-Pattern/FlyWithWings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FLYWITHWINGS_HPP 2 | #define FLYWITHWINGS_HPP 3 | 4 | #include "FlyBehavior.hpp" 5 | 6 | #include 7 | 8 | class FlyWithWings : public FlyBehavior { 9 | public: 10 | void fly() { 11 | std::cout << "I'm flying" << std::endl; 12 | } 13 | }; 14 | 15 | #endif -------------------------------------------------------------------------------- /Decorator-Pattern/Espresso.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ESPRESSO_HPP 2 | #define ESPRESSO_HPP 3 | 4 | #include "Beverage.hpp" 5 | 6 | class Espresso : public Beverage { 7 | public: 8 | std::string getDescription() { 9 | return "Espresso"; 10 | } 11 | 12 | double cost() { 13 | return 1.99; 14 | } 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /Observer-Pattern/Subject.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SUBJECT_HPP 2 | #define SUBJECT_HPP 3 | 4 | class Observer; 5 | 6 | class Subject { 7 | public: 8 | virtual ~Subject() = default; 9 | virtual void registerObserver(Observer*) = 0; 10 | virtual void removeObserver(Observer*) = 0; 11 | virtual void notifyObservers() = 0; 12 | }; 13 | 14 | #endif -------------------------------------------------------------------------------- /Decorator-Pattern/Beverage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BEVERAGE_HPP 2 | #define BEVERAGE_HPP 3 | 4 | #include 5 | 6 | class Beverage { 7 | public: 8 | virtual std::string getDescription() { 9 | return "Unkown Beverage"; 10 | } 11 | 12 | virtual double cost() = 0; 13 | virtual ~Beverage() = default; 14 | }; 15 | 16 | 17 | #endif -------------------------------------------------------------------------------- /Decorator-Pattern/HouseBlend.hpp: -------------------------------------------------------------------------------- 1 | #ifndef HOUSEBLEND_HPP 2 | #define HOUSEBLEND_HPP 3 | 4 | #include "Beverage.hpp" 5 | 6 | class HouseBlend : public Beverage { 7 | public: 8 | std::string getDescription() { 9 | return "House Blend Coffee"; 10 | } 11 | 12 | double cost() { 13 | return .89; 14 | } 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /Proxy/README.md: -------------------------------------------------------------------------------- 1 | # Proxy 2 | 3 | ## 动机(Motivation) 4 | + 在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等), 5 | 直接访问会给使用者、或者系统结构带来很多麻烦。 6 | + 如何在不失去透明操作对象的同事来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常见的解决方式。 7 | 8 | ## 模式定义 9 | 为其他对象提供一种代理以控制(隔离,使用接口)对这对象的访问。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + Proxy并不一定要求保持接口完整的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。 14 | -------------------------------------------------------------------------------- /Memento/README.md: -------------------------------------------------------------------------------- 1 | # Memento(备忘录) 2 | 3 | ## 动机(Motivation) 4 | + 某些对象的状态转换过程中,可能由于某中需要,要求程序能够回溯到对象之前处于某个点的状态。 5 | 如果使用一些公开接口来让其他对象得到对象的状态,便会暴露对象的细节实现。 6 | + 如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对象本身的封装性、 7 | 8 | ## 模式定义 9 | 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + 备忘录存储原发器(Originator)对象的内部状态,在需要时恢复原发器状态。 14 | + 有些过时。 15 | -------------------------------------------------------------------------------- /Strategy-Pattern/DecoyDuck.cpp: -------------------------------------------------------------------------------- 1 | #include "DecoyDuck.hpp" 2 | 3 | #include "FlyNoWay.hpp" 4 | #include "MuteQuack.hpp" 5 | 6 | #include 7 | 8 | DecoyDuck::DecoyDuck() : 9 | Duck(std::make_unique(), std::make_unique()) { 10 | } 11 | 12 | void DecoyDuck::display() { 13 | std::cout << "I'm a real decoy duck" << std::endl; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Strategy-Pattern/RubberDuck.cpp: -------------------------------------------------------------------------------- 1 | #include "RubberDuck.hpp" 2 | 3 | #include "FlyNoWay.hpp" 4 | #include "Squeak.hpp" 5 | 6 | #include 7 | 8 | RubberDuck::RubberDuck() : 9 | Duck(std::make_unique(), std::make_unique()) { 10 | } 11 | 12 | void RubberDuck::display() { 13 | std::cout << "I'm a real rubber duck" << std::endl; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Template-Pattern/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Tea.hpp" 2 | #include "Coffee.hpp" 3 | 4 | int main() { 5 | Tea* tea = new Tea(); 6 | Coffee* coffee = new Coffee(); 7 | 8 | std::cout << "\nMaking tea...\n"; 9 | tea->prepareRecipe(); 10 | 11 | std::cout << "\nMaking coffee...\n"; 12 | coffee->prepareRecipe(); 13 | 14 | delete tea; 15 | delete coffee; 16 | } -------------------------------------------------------------------------------- /State/README.md: -------------------------------------------------------------------------------- 1 | # State 2 | 3 | ## 动机(Motivation) 4 | + 对象状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。 5 | + 如何在运行时根据对象的状态来透明地改变对象的行为? 6 | 7 | 8 | ## 模式定义 9 | 允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + State模式将所有与一个特定状态相关的行为都放入一个State的子对象中,在对象状态切换时,切换相应的对象; 14 | 但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。 15 | + 转换是原子性的 16 | + 与Strategy模式类似 17 | -------------------------------------------------------------------------------- /Strategy-Pattern/MallardDuck.cpp: -------------------------------------------------------------------------------- 1 | #include "MallardDuck.hpp" 2 | 3 | #include "FlyWithWings.hpp" 4 | #include "Quack.hpp" 5 | 6 | #include 7 | 8 | MallardDuck::MallardDuck() : 9 | Duck(std::make_unique(), std::make_unique()) { 10 | } 11 | 12 | void MallardDuck::display() { 13 | std::cout << "I'm a real mallard duck" << std::endl; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Strategy-Pattern/RedHeadDuck.cpp: -------------------------------------------------------------------------------- 1 | #include "RedHeadDuck.hpp" 2 | 3 | #include "FlyWithWings.hpp" 4 | #include "Quack.hpp" 5 | 6 | #include 7 | 8 | RedHeadDuck::RedHeadDuck() : 9 | Duck(std::make_unique(), std::make_unique()) { 10 | } 11 | 12 | void RedHeadDuck::display() { 13 | std::cout << "I'm a real red head duck" << std::endl; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Command-Pattern/SimpleRemoteControl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLEREMOTECONTROL_HPP 2 | #define SIMPLEREMOTECONTROL_HPP 3 | 4 | #include "Command.hpp" 5 | 6 | class SimpleRemoteControl { 7 | private: 8 | Command *slot; 9 | 10 | public: 11 | void setCommand(Command *command) { 12 | slot = command; 13 | } 14 | 15 | void buttonWasPressed() { 16 | slot->execute(); 17 | } 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /Factory Method/FileSplitter1.cpp: -------------------------------------------------------------------------------- 1 | class ISplitter{ 2 | public: 3 | virtual void split()=0; 4 | virtual ~ISplitter(){} 5 | }; 6 | 7 | class BinarySplitter : public ISplitter{ 8 | 9 | }; 10 | 11 | class TxtSplitter: public ISplitter{ 12 | 13 | }; 14 | 15 | class PictureSplitter: public ISplitter{ 16 | 17 | }; 18 | 19 | class VideoSplitter: public ISplitter{ 20 | 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /Factory-Pattern/main.cpp: -------------------------------------------------------------------------------- 1 | #include "NYPizzaStore.hpp" 2 | #include "ChicagoPizzaStore.hpp" 3 | #include "PizzaStore.hpp" 4 | #include "Pizza.hpp" 5 | 6 | int main() 7 | { 8 | auto nyStore = new NYPizzaStore(); 9 | auto chicagoStore = new ChicagoPizzaStore(); 10 | 11 | auto nyCheese = nyStore->orderPizza("cheese"); 12 | auto chicagoCheese = chicagoStore->orderPizza("cheese"); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Chain of Resposibility/README.md: -------------------------------------------------------------------------------- 1 | # Chain of Resposibility(职责链) 2 | 3 | ## 动机(Motivation) 4 | + 一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接收者,如果显式指定,将必不可少地带来请求发送者与接收者的紧耦合。 5 | + 如何使请求的发送者不需要指定具体的接收者?让请求的接收者自己在运行时决定来处理请求,从而使两者解耦。 6 | 7 | ## 模式定义 8 | 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + 应用于”一个请求可能有多个接受者,但是最后真正的接受者只有一个“,这时候请求发送者与接受者有可能出现”变化脆弱“的症状,职责链解耦。 13 | + 有些过时。 14 | -------------------------------------------------------------------------------- /Mediator/README.md: -------------------------------------------------------------------------------- 1 | # Mediator 2 | 3 | ## 动机(Motivation) 4 | + 多个对象相互关联的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。 5 | + 在这种情况下,可以使用一种”中介对象“来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。 6 | 7 | ## 模式定义 8 | 用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各对象不需要显式的相互引用(编译时依赖->运行时依赖), 9 | 从而使其耦合松散(管理变化),并且可以独立地改变它们之间的交互。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + 将多个对象间发杂的关联关系解耦 14 | + Facade模式是解耦系统间(单向)的对象关联关系;Mediator模式是解耦系统内各个对象之间(双向)的关联关系。 15 | -------------------------------------------------------------------------------- /Command/README.md: -------------------------------------------------------------------------------- 1 | # Command 2 | 3 | ## 动机(Motivation) 4 | + ”行为请求者“与”行为实现者“通常呈现一种”紧耦合“。但在某些场合——比如需要对行为进行”记录、撤销、事务“等处理,这种无法抵御变化的紧耦合是不合适的。 5 | + 在这种情况下,如何将”行为请求者“与”行为实现者“解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。 6 | 7 | ## 模式定义 8 | 将一个请求(行为)封装成一个对象,从而使你可用不用的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + Command模式的根本目的在于将”行为请求者“与”行为实现者“解耦,在面向对象语言中,常见的实现手段是”将行为抽象为对象“。 13 | + 与C++中的函数对象类似,C++函数对象以函数签名来定义行为接口规范,更灵活性能更高。 14 | -------------------------------------------------------------------------------- /Singleton/README.md: -------------------------------------------------------------------------------- 1 | # Singleton 2 | 3 | ## 动机(Motivation) 4 | + 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。 5 | + 如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例? 6 | + 这应该是类设计者的责任,而不是使用者的责任。 7 | 8 | ## 模式定义 9 | 保证一个类仅有一个实例,并提供一个该实例的全局访问点。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + Singleton模式中的实例构造器可以设置为protected以允许子类派生。 14 | + Singleton模式一般不要支持拷贝构造函数和Clone接口,因为这有可能导致多个对象实例,与Singleton模式的初中违背。 15 | + 如何实现多线程环境下安全的Singleton?注意对双检查锁的正确实现。 16 | -------------------------------------------------------------------------------- /Observer/MainForm1.cpp: -------------------------------------------------------------------------------- 1 | class MainForm : public Form 2 | { 3 | TextBox* txtFilePath; 4 | TextBox* txtFileNumber; 5 | ProgressBar* progressBar; 6 | 7 | public: 8 | void Button1_Click(){ 9 | 10 | string filePath = txtFilePath->getText(); 11 | int number = atoi(txtFileNumber->getText().c_str()); 12 | 13 | FileSplitter splitter(filePath, number, progressBar); 14 | 15 | splitter.split(); 16 | 17 | } 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /Decorator-Pattern/CondimentDecorator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CONDIMENTDECORATOR_HPP 2 | #define CONDIMENTDECORATOR_HPP 3 | 4 | #include "Beverage.hpp" 5 | 6 | #include 7 | 8 | class CondimentDecorator : public Beverage { 9 | protected: 10 | std::unique_ptr beverage; 11 | public: 12 | CondimentDecorator(std::unique_ptr b) : beverage(std::move(b)) {} 13 | virtual ~CondimentDecorator() = default; 14 | }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /Iterator/README.md: -------------------------------------------------------------------------------- 1 | # Iterator 2 | 3 | ## 动机(Motivation) 4 | + 集合对象内部结构常常变化异常。但对于这些集合对象,我们希望不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素; 5 | 同时这种”透明遍历“也为”同一种算法在多种集合对象上进行操作“提供了可能。 6 | + 使用面向对象技术将这种遍历机制抽象为”迭代器对象“为”应对变化中的集合对象“提供了一种优雅的方式。 7 | 8 | ## 模式定义 9 | 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露(稳定)该对象的内部表示。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + 迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。 14 | + 迭代多态:为遍历不同的集合对象提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。 15 | + 对C++来说是过时的,现在迭代器用模板,面向对象的方式性能低 16 | -------------------------------------------------------------------------------- /Command-Pattern/GarageDoorOpen.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GARAGEDOOROPEN_HPP 2 | #define GARAGEDOOROPEN_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include "Command.hpp" 8 | 9 | class GarageDoorOpen : public Command { 10 | private: 11 | std::string door; 12 | public: 13 | GarageDoorOpen(std::string g) : door(g) {} 14 | 15 | void execute() { 16 | std::cout << door << " was opened" << std::endl; 17 | } 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /Command-Pattern/LightOnCommand.hpp: -------------------------------------------------------------------------------- 1 | #ifndef LIGHTONCOMMAND_HPP 2 | #define LIGHTONCOMMAND_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include "Command.hpp" 8 | 9 | class LightOnCommand : public Command { 10 | private: 11 | std::string light; 12 | public: 13 | LightOnCommand(std::string l) : light(l) {} 14 | 15 | void execute() { 16 | std::cout << light << " was turned on" << std::endl; 17 | } 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /Factory-Pattern/NYStyleCheesePizza.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NYSTYLECHEESEPIZZA_HPP 2 | #define NYSTYLECHEESEPIZZA_HPP 3 | 4 | #include "Pizza.hpp" 5 | 6 | class NYStyleCheesePizza : public Pizza { 7 | public: 8 | NYStyleCheesePizza() 9 | { 10 | name = "NY Style sauce and cheese pizza"; 11 | dough = "Thin crust dough"; 12 | sauce = "Marinara sauce"; 13 | toppings.push_back("Gratted reggiano cheese"); 14 | } 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /Decorator-Pattern/Mocha.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MOCHA_HPP 2 | #define MOCHA_HPP 3 | 4 | #include "CondimentDecorator.hpp" 5 | 6 | class Mocha : public CondimentDecorator { 7 | public: 8 | Mocha(std::unique_ptr b) : CondimentDecorator(std::move(b)) {} 9 | 10 | std::string getDescription() { 11 | return beverage->getDescription() + ", Mocha"; 12 | } 13 | 14 | double cost() { 15 | return .20 + beverage->cost(); 16 | } 17 | }; 18 | 19 | #endif -------------------------------------------------------------------------------- /Facade/README.md: -------------------------------------------------------------------------------- 1 | # Façade(门面模式) 2 | 3 | ## 动机(Motivation) 4 | + 客户和组件中各种复杂的子系统有过多的耦合 5 | + 如何简化外部客户程序和系统间的交互接口?如何解耦? 6 | 7 | ## 模式定义 8 | 为子系统中的一组接口提供一个一致(稳定)的界面,Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用(复用)。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + 从客户程序角度来看,Façade模式简化了整个组件系统的接口,对于组件内部与外部的客户程序来说, 13 | 达到了一种”解耦“的效果——内部子系统的任何变化不会影响到Façade接口的变化。 14 | + Façade设计模式更注重架构的层次去看整个系统,而不是单个类的层次。Façade很多时候是一种架构设计模式。 15 | + Façade设计模式并非一个集装箱,可以任意地放进任何多个对象。Façade模式组件中的内部应该是”相互耦合关系比较大的一系列组件“,而不是一个简单的功能集合。 16 | -------------------------------------------------------------------------------- /Abstract Factory/README.md: -------------------------------------------------------------------------------- 1 | # Abstract Factory 2 | 3 | ## 动机(motivation) 4 | + 在软件系统中,经常面临着“一系列相互依赖的对象工作”;同时,由于需求的变化,往往存在更多系列对象的创建工作。 5 | + 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合。 6 | 7 | ## 模式定义 8 | 提供一个接口,让该接口负责创建一系列”相关或者相互依赖的对象“,无需指定它们具体的类。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + 如果没有应对”多系列对象创建“的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂即可。 13 | + ”系列对象“指的是在某一个特定系列的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。 14 | + Abstract Factory模式主要在于应用”新系列“的需求变动。其缺点在与难以应对”新对象“的需求变动。 15 | -------------------------------------------------------------------------------- /Factory-Pattern/ChicagoStyleCheesePizza.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CHICAGOSTYLECHEESEPIZZA_HPP 2 | #define CHICAGOSTYLECHEESEPIZZA_HPP 3 | 4 | #include "Pizza.hpp" 5 | 6 | class ChicagoStyleCheesePizza: public Pizza 7 | { 8 | public: 9 | ChicagoStyleCheesePizza() 10 | { 11 | name = "Chicago Style Deep Dish Pizza"; 12 | dough = "Extra thick crust dough"; 13 | sauce = "Plum tomato sauce"; 14 | toppings.push_back("Shredded mozzarella"); 15 | } 16 | }; 17 | 18 | #endif -------------------------------------------------------------------------------- /Flyweight/README.md: -------------------------------------------------------------------------------- 1 | # Flyweight 2 | 3 | ## 动机(Motivation) 4 | + 在软件系统采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价。 5 | + 如何在避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作? 6 | 7 | ## 模式定义 8 | 运行共享技术有效地支持大量细粒度的对象。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + 面向对象很好地解决了抽象性的问题,但是作为yield运行机器中的程序实体,我们需要考虑对象的代价问题, 13 | Flyweight主要解决面向对象的大家问题,一般不触及面向对象的抽象性问题。 14 | + Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的压力。在具体实现方面,要注意对象状态的处理。 15 | + 对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。 16 | -------------------------------------------------------------------------------- /Bridge/README.md: -------------------------------------------------------------------------------- 1 | # Bridge 2 | 3 | ## 动机(Motivation) 4 | + 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。 5 | + 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度? 6 | 7 | ## 模式定义 8 | 将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。 13 | + Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。 14 | + Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。 15 | -------------------------------------------------------------------------------- /Interpreter/README.md: -------------------------------------------------------------------------------- 1 | # Interpreter 2 | 3 | ## 动机(Motivation) 4 | + 如果某一特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。 5 | + 在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。 6 | 7 | ## 模式定义 8 | 给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。 9 | ——《设计模式》GoF 10 | 11 | 12 | ## 要点总结 13 | + Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现, 14 | 并且容易抽象为语法规则的问题”才适合使用Interpreter模式。 15 | + 使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。 16 | + Interpreter模式适合简单的文法表示,对于复杂的文法表示需要求助语法分析器标准工具。 17 | -------------------------------------------------------------------------------- /Strategy/README.md: -------------------------------------------------------------------------------- 1 | # Strategy 2 | 3 | ## 动机(Motivation) 4 | + 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。 5 | + 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题? 6 | 7 | ## 模式定义 8 | 定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。 9 | ——《设计模式》 GoF 10 | 11 | ## 要点总结 12 | + Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。 13 | + Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。 14 | + 如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。 15 | -------------------------------------------------------------------------------- /Factory Method/README.md: -------------------------------------------------------------------------------- 1 | # Factory Method 2 | 3 | ## 动机(Motivation) 4 | + 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。 5 | + 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合? 6 | 7 | ## 模式定义 8 | 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。 13 | + Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。 14 | + Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。 15 | -------------------------------------------------------------------------------- /Prototype/README.md: -------------------------------------------------------------------------------- 1 | # Prototype 2 | 3 | ## 动机(motivation) 4 | + 在软件系统中,经常面临这“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。 5 | + 如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”,从而使得依赖这些”易变对象“的客户程序不随着需求改变而改变。 6 | 7 | ## 模式定义 8 | 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。 9 | ——《设计模式》GoF 10 | 11 | ## 要点总结 12 | + Prototype模式同样用于隔离对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有稳定的接口。 13 | + Prototype模式对于“如何创建易变类的实体对象“采用”原型克隆“的方法来做, 14 | 它使得我们可以非常灵活地动态创建”拥有某些稳定接口“的新对象——所需工作仅仅是注册一个新类的对象(即原型), 15 | 然后在任何需要的地方Clone。 16 | + Prototype模式中的Clone方法可以利用某些框架中的序列化来实现深拷贝。 17 | -------------------------------------------------------------------------------- /Proxy/client.cpp: -------------------------------------------------------------------------------- 1 | class ISubject{ 2 | public: 3 | virtual void process(); 4 | }; 5 | 6 | 7 | class RealSubject: public ISubject{ 8 | public: 9 | virtual void process(){ 10 | //.... 11 | } 12 | }; 13 | 14 | class ClientApp{ 15 | 16 | ISubject* subject; 17 | 18 | public: 19 | 20 | ClientApp(){ 21 | subject=new RealSubject(); 22 | } 23 | 24 | void DoTask(){ 25 | //... 26 | subject->process(); 27 | 28 | //.... 29 | } 30 | }; -------------------------------------------------------------------------------- /Observer/README.md: -------------------------------------------------------------------------------- 1 | # Observer 2 | 3 | ## 动机(Motivation) 4 | + 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对 5 | 象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。 6 | + 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。 7 | 8 | ## 模式定义 9 | 定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 10 | ——《 设计模式》 GoF 11 | 12 | 13 | ## 要点总结 14 | + 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。 15 | + 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。 16 | + 观察者自己决定是否需要订阅通知,目标对象对此一无所知。 17 | + Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分。 18 | -------------------------------------------------------------------------------- /Builder/README.md: -------------------------------------------------------------------------------- 1 | # Builder 2 | 3 | ## 动机(Motivation) 4 | + 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这 5 | 个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。 6 | + 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变? 7 | 8 | 9 | ## 模式定义 10 | 将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。 11 | ——《设计模式》GoF 12 | 13 | 14 | ## 要点总结 15 | + Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。 16 | + 变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。 17 | + 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++(构造函数中不可以调用虚函数) vs. C#)。 18 | -------------------------------------------------------------------------------- /Decorator-Pattern/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Espresso.hpp" 2 | #include "Mocha.hpp" 3 | #include "HouseBlend.hpp" 4 | 5 | #include 6 | 7 | int main() { 8 | std::unique_ptr b2 = std::make_unique(); 9 | b2 = std::make_unique(std::move(b2)); 10 | std::cout << b2->getDescription() << " $" << b2->cost() << std::endl; 11 | 12 | std::unique_ptr b3 = std::make_unique(); 13 | b3 = std::make_unique(std::move(b3)); 14 | std::cout << b3->getDescription() << " $" << b3->cost() << std::endl; 15 | } -------------------------------------------------------------------------------- /Composite/README.md: -------------------------------------------------------------------------------- 1 | # Composite 2 | 3 | ## 动机(Motivation) 4 | + 客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象结构)的变化 5 | 引起客户代码的频繁变化,带来了代码的维护性、扩展性等弊端。 6 | + 如何将”客户代码与复杂的对象容器结构“解耦?让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器? 7 | 8 | ## 模式定义 9 | 将对象组合成树形结构以表示”部分-整体“的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性(稳定)。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + Composite模式采用树性结构来实现普遍存在的对象容器,从而将”一对多“的关系转化为”一对一“的关系,使得客户代码可以一致地(复用)处理对象和对象容器, 14 | 无需关心处理的是单个的对象,还是组合的对象容器。 15 | + 客户代码与纯粹的抽象接口——而非对象容器的内部实现结构——发生依赖,从而更能”应对变化“。 16 | + Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技术来改善效率。 17 | -------------------------------------------------------------------------------- /Abstract Factory/EmployeeDAO1.cpp: -------------------------------------------------------------------------------- 1 | 2 | class EmployeeDAO{ 3 | 4 | public: 5 | vector GetEmployees(){ 6 | SqlConnection* connection = 7 | new SqlConnection(); 8 | connection->ConnectionString = "..."; 9 | 10 | SqlCommand* command = 11 | new SqlCommand(); 12 | command->CommandText="..."; 13 | command->SetConnection(connection); 14 | 15 | SqlDataReader* reader = command->ExecuteReader(); 16 | while (reader->Read()){ 17 | 18 | } 19 | 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /Command-Pattern/main.cpp: -------------------------------------------------------------------------------- 1 | #include "LightOnCommand.hpp" 2 | #include "SimpleRemoteControl.hpp" 3 | #include "GarageDoorOpen.hpp" 4 | 5 | int main() { 6 | SimpleRemoteControl *remote = new SimpleRemoteControl(); 7 | LightOnCommand *lightOn = new LightOnCommand("my light"); 8 | 9 | remote->setCommand(lightOn); 10 | remote->buttonWasPressed(); 11 | 12 | GarageDoorOpen *doorOpen = new GarageDoorOpen("my garage door"); 13 | remote->setCommand(doorOpen); 14 | remote->buttonWasPressed(); 15 | 16 | delete remote; 17 | delete lightOn; 18 | delete doorOpen; 19 | } -------------------------------------------------------------------------------- /Visitor/README.md: -------------------------------------------------------------------------------- 1 | # Visitor 2 | 3 | ## 动机(Motivation) 4 | + 由于需求的变化,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改, 5 | 将会给子类带来很繁重的变更负担,甚至破坏原有设计。 6 | + 如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上面的问题? 7 | 8 | ## 模式定义 9 | 表示一个作用与某对象结构中的各元素的操作。使得可以在不改变(稳定)各元素的类的前提下定义(扩展) 10 | 作用于这些元素的新操作(变化)。 11 | ——《设计模式》GoF 12 | 13 | ## 要点总结 14 | + Visitor模式通过所谓的双重分发来实现在不更改(编译时)Element类层次结构的前提下,在运行时 15 | 透明地为类层次结构上的各个类动态添加新的操作(支持变化)。 16 | + 所谓双重分发Visitor模式中间包括了两个多态分发:第一个为accept方法的多态辨析;第二个为visitElement方法的多态辨析。 17 | + Visitor模式的最大缺点在于扩展类层次结构(添加新的Element子类),会导致Visitor类的改变, 18 | 因此Visitor模式适用于“Element类层次结构稳定,而其中的操作却经常面临频繁改动”。 19 | -------------------------------------------------------------------------------- /Proxy/proxy.cpp: -------------------------------------------------------------------------------- 1 | class ISubject{ 2 | public: 3 | virtual void process(); 4 | }; 5 | 6 | 7 | //Proxy的设计 8 | class SubjectProxy: public ISubject{ 9 | 10 | 11 | public: 12 | virtual void process(){ 13 | //对RealSubject的一种间接访问 14 | //.... 15 | } 16 | }; 17 | 18 | class ClientApp{ 19 | 20 | ISubject* subject; 21 | 22 | public: 23 | 24 | ClientApp(){ 25 | subject=new SubjectProxy(); 26 | } 27 | 28 | void DoTask(){ 29 | //... 30 | subject->process(); 31 | 32 | //.... 33 | } 34 | }; -------------------------------------------------------------------------------- /Observer-Pattern/main.cpp: -------------------------------------------------------------------------------- 1 | #include "WeatherData.hpp" 2 | #include "CurrentConditionsDisplay.hpp" 3 | 4 | void WeatherStationWithFunctions() 5 | { 6 | auto w = std::make_shared(); 7 | CurrentConditionsDisplay* currentDisplay = new CurrentConditionsDisplay(w); 8 | currentDisplay->registerObserver(); 9 | // 只要主题的值改变了,就会通知观察者即CurrentConditionsDisplay,然后观察者打印出来 10 | w->setMeasurements(80, 65, 30.4f); 11 | w->setMeasurements(82, 70, 29.2f); 12 | w->setMeasurements(78, 90, 29.2f); 13 | delete currentDisplay; 14 | } 15 | 16 | int main() 17 | { 18 | WeatherStationWithFunctions(); 19 | } 20 | -------------------------------------------------------------------------------- /Factory-Pattern/ChicagoStylePepperoniPizza.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CHICAGOSTYLEPEPPERONIPIZZA_HPP 2 | #define CHICAGOSTYLEPEPPERONIPIZZA_HPP 3 | 4 | #include "Pizza.hpp" 5 | 6 | class ChicagoStylePepperoniPizza: public Pizza 7 | { 8 | public: 9 | ChicagoStylePepperoniPizza() 10 | { 11 | name = "Chicago Style Pepperoni Pizza"; 12 | dough = "Extra thick crust dough"; 13 | sauce = "Plum tomato sauce"; 14 | toppings.push_back("Shredded mozzarella"); 15 | toppings.push_back("Sliced pepperoni"); 16 | toppings.push_back("No olives or eggplant because that should not go on a pizza"); 17 | } 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /Template Method/README.md: -------------------------------------------------------------------------------- 1 | # Template Method 2 | 3 | ## 动机(Motivation) 4 | + 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。 5 | + 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求? 6 | 7 | 8 | ## 模式定义 9 | 定义一个操作中的算法的骨架 **(稳定)** ,而将一些步骤延迟 **(变化)** 到子类中。 10 | Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的 11 | 某些特定步骤。 12 | ——《 设计模式》 GoF 13 | 14 | 15 | ## 要点总结 16 | + Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性) 17 | 为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。 18 | + 除了可以灵活应对子步骤的变化外, **“不要调用我,让我来调用你”** 的反向控制结构是Template Method的典型应用。 19 | + 在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。 20 | -------------------------------------------------------------------------------- /Factory-Pattern/PizzaStore.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PIZZASTORE_HPP 2 | #define PIZZASTORE_HPP 3 | 4 | #include "Pizza.hpp" 5 | 6 | #include 7 | 8 | class PizzaStore { 9 | public: 10 | std::unique_ptr orderPizza(std::string type) { 11 | auto pizza = createPizza(type); 12 | if(pizza != nullptr) 13 | { 14 | std::cout << "\n--- Making a " + pizza->getName() + " ---\n \n"; 15 | pizza->prepare(); 16 | pizza->bake(); 17 | pizza->cut(); 18 | pizza->box(); 19 | } 20 | return pizza; 21 | } 22 | virtual std::unique_ptr createPizza(std::string type) = 0; 23 | }; 24 | 25 | #endif -------------------------------------------------------------------------------- /Template-Pattern/Tea.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEA_HPP 2 | #define TEA_HPP 3 | 4 | #include "CaffeineBeverage.hpp" 5 | 6 | #include 7 | 8 | class Tea : public CaffeineBeverage { 9 | public: 10 | ~Tea(){} 11 | 12 | void brew() { 13 | std::cout << "Steeping the tea\n"; 14 | } 15 | 16 | void addCondiments() { 17 | std::cout << "Adding Lemon\n"; 18 | } 19 | 20 | bool customerWantsCondiments() 21 | { 22 | char c; 23 | std::cout << "Do you want to add condiments?\n"; 24 | std::cin >> c; 25 | 26 | if (c == 'y') 27 | return true; 28 | else 29 | return false; 30 | } 31 | }; 32 | 33 | #endif -------------------------------------------------------------------------------- /Factory-Pattern/NYPizzaStore.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NYPIZZASTORE_HPP 2 | #define NYPIZZASTORE_HPP 3 | 4 | #include "PizzaStore.hpp" 5 | #include "NYStyleCheesePizza.hpp" 6 | #include "NYStylePepperoniPizza.hpp" 7 | 8 | class NYPizzaStore : public PizzaStore { 9 | public: 10 | std::unique_ptr createPizza(std::string type) { 11 | std::unique_ptr pizza = nullptr; 12 | 13 | if (type == "cheese") 14 | { 15 | pizza = std::make_unique(); 16 | } 17 | else if (type == "pepperoni") 18 | { 19 | pizza = std::make_unique(); 20 | } 21 | return pizza; 22 | } 23 | }; 24 | 25 | #endif -------------------------------------------------------------------------------- /Factory-Pattern/NYStylePepperoniPizza.hpp: -------------------------------------------------------------------------------- 1 | #ifndef NYSTYLEPEPPERONIPIZZA_HPP 2 | #define NYSTYLEPEPPERONIPIZZA_HPP 3 | 4 | #include "Pizza.hpp" 5 | 6 | class NYStylePepperoniPizza: public Pizza 7 | { 8 | public: 9 | NYStylePepperoniPizza() 10 | { 11 | name = "NY style pepperoni pizza"; 12 | dough = "Thin crust dough"; 13 | sauce = "Marinara sauce"; 14 | toppings.push_back("Grated reggiano cheese"); 15 | toppings.push_back("Sliced pepperoni"); 16 | toppings.push_back("Garlic"); 17 | toppings.push_back("Onion"); 18 | toppings.push_back("Mushrooms"); 19 | toppings.push_back("Red pepper"); 20 | } 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /Decorator/README.md: -------------------------------------------------------------------------------- 1 | # Decorator 2 | 3 | ## 动机(Motivation) 4 | + 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性; 5 | 并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。 6 | + 如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低? 7 | 8 | ## 模式定义 9 | 动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)。 10 | ——《设计模式》GoF 11 | 12 | ## 要点总结 13 | + 通过采用组合而非继承的手法, Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。 14 | 避免了使用继承带来的“灵活性差”和“多子类衍生问题”。 15 | + Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。 16 | 但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。 17 | + Decorator模式的目的并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。 18 | -------------------------------------------------------------------------------- /Template-Pattern/Coffee.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COFFEE_HPP 2 | #define COFFEE_HPP 3 | 4 | #include "CaffeineBeverage.hpp" 5 | 6 | #include 7 | 8 | class Coffee : public CaffeineBeverage { 9 | public: 10 | ~Coffee(){} 11 | 12 | void brew() { 13 | std::cout << "Dripping Coffee through filter\n"; 14 | } 15 | 16 | void addCondiments() { 17 | std::cout << "Adding Sugar and Milk\n"; 18 | } 19 | 20 | bool customerWantsCondiments() { 21 | char c; 22 | std::cout << "Do you want to add condiments?\n"; 23 | std::cin >> c; 24 | 25 | if(c == 'y') 26 | return true; 27 | else 28 | return false; 29 | } 30 | }; 31 | 32 | 33 | #endif -------------------------------------------------------------------------------- /Prototype/ConcretePrototype.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | //具体类 4 | class BinarySplitter : public ISplitter{ 5 | public: 6 | virtual ISplitter* clone(){ 7 | return new BinarySplitter(*this); 8 | } 9 | }; 10 | 11 | class TxtSplitter: public ISplitter{ 12 | public: 13 | virtual ISplitter* clone(){ 14 | return new TxtSplitter(*this); 15 | } 16 | }; 17 | 18 | class PictureSplitter: public ISplitter{ 19 | public: 20 | virtual ISplitter* clone(){ 21 | return new PictureSplitter(*this); 22 | } 23 | }; 24 | 25 | class VideoSplitter: public ISplitter{ 26 | public: 27 | virtual ISplitter* clone(){ 28 | return new VideoSplitter(*this); 29 | } 30 | }; 31 | 32 | 33 | -------------------------------------------------------------------------------- /Factory-Pattern/ChicagoPizzaStore.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CHICAGOPIZZASTORE_HPP 2 | #define CHICAGOPIZZASTORE_HPP 3 | 4 | #include "PizzaStore.hpp" 5 | #include "ChicagoStyleCheesePizza.hpp" 6 | #include "ChicagoStylePepperoniPizza.hpp" 7 | 8 | class ChicagoPizzaStore : public PizzaStore { 9 | public: 10 | std::unique_ptr createPizza(std::string type) { 11 | std::unique_ptr pizza = nullptr; 12 | 13 | if (type == "cheese") 14 | { 15 | pizza = std::make_unique(); 16 | } 17 | else if (type == "pepperoni") 18 | { 19 | pizza = std::make_unique(); 20 | } 21 | return pizza; 22 | } 23 | }; 24 | 25 | #endif -------------------------------------------------------------------------------- /Template-Pattern/CaffeineBeverage.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CAFFEINEBEVERAGE_HPP 2 | #define CAFFEINEBEVERAGE_HPP 3 | 4 | #include 5 | 6 | class CaffeineBeverage { 7 | public: 8 | virtual ~CaffeineBeverage(){} 9 | 10 | void prepareRecipe() { 11 | boilWater(); 12 | brew(); 13 | pourInCup(); 14 | if(customerWantsCondiments()) 15 | addCondiments(); 16 | } 17 | 18 | virtual void brew() = 0; 19 | virtual void addCondiments() = 0; 20 | 21 | void boilWater() { 22 | std::cout << "Boiling water\n"; 23 | } 24 | 25 | void pourInCup() { 26 | std::cout << "Pouring into cup\n"; 27 | } 28 | 29 | virtual bool customerWantsCondiments() { 30 | return true; 31 | } 32 | }; 33 | 34 | 35 | #endif -------------------------------------------------------------------------------- /Flyweight/flyweight.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Font { 3 | private: 4 | 5 | //unique object key 6 | string key; 7 | 8 | //object state 9 | //.... 10 | 11 | public: 12 | Font(const string& key){ 13 | //... 14 | } 15 | }; 16 | ß 17 | 18 | class FontFactory{ 19 | private: 20 | map fontPool; 21 | 22 | public: 23 | Font* GetFont(const string& key){ 24 | 25 | map::iterator item=fontPool.find(key); 26 | 27 | if(item!=footPool.end()){ 28 | return fontPool[key]; 29 | } 30 | else{ 31 | Font* font = new Font(key); 32 | fontPool[key]= font; 33 | return font; 34 | } 35 | 36 | } 37 | 38 | void clear(){ 39 | //... 40 | } 41 | }; -------------------------------------------------------------------------------- /Strategy-Pattern/Duck.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DUCK_HPP 2 | #define DUCK_HPP 3 | 4 | #include "FlyBehavior.hpp" 5 | #include "QuackBehavior.hpp" 6 | 7 | #include 8 | #include 9 | 10 | class Duck { 11 | public: 12 | std::unique_ptr flyBehavior; 13 | std::unique_ptr quackBehavior; 14 | 15 | Duck(std::unique_ptr fb, std::unique_ptr qb) : flyBehavior(std::move(fb)), quackBehavior(std::move(qb)) {} 16 | 17 | virtual ~Duck(){} 18 | 19 | // 下面两个函数使用了多态 20 | void performFly(){ 21 | flyBehavior->fly(); 22 | } 23 | 24 | void performQuack(){ 25 | quackBehavior->quack(); 26 | } 27 | 28 | void swim(){ 29 | std::cout << "All ducks swim!" << std::endl; 30 | } 31 | virtual void display(){} 32 | }; 33 | 34 | 35 | #endif -------------------------------------------------------------------------------- /Visitor/Visitor2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Visitor; 5 | 6 | 7 | class Element 8 | { 9 | public: 10 | virtual void Func1() = 0; 11 | 12 | virtual void Func2(int data)=0; 13 | virtual void Func3(int data)=0; 14 | //... 15 | 16 | virtual ~Element(){} 17 | }; 18 | 19 | class ElementA : public Element 20 | { 21 | public: 22 | void Func1() override{ 23 | //... 24 | } 25 | 26 | void Func2(int data) override{ 27 | //... 28 | } 29 | 30 | }; 31 | 32 | class ElementB : public Element 33 | { 34 | public: 35 | void Func1() override{ 36 | //*** 37 | } 38 | 39 | void Func2(int data) override { 40 | //*** 41 | } 42 | 43 | }; 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Memento/memento.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Memento 3 | { 4 | string state; 5 | //.. 6 | public: 7 | Memento(const string & s) : state(s) {} 8 | string getState() const { return state; } 9 | void setState(const string & s) { state = s; } 10 | }; 11 | 12 | 13 | 14 | class Originator 15 | { 16 | string state; 17 | //.... 18 | public: 19 | Originator() {} 20 | Memento createMomento() { 21 | Memento m(state); 22 | return m; 23 | } 24 | void setMomento(const Memento & m) { 25 | state = m.getState(); 26 | } 27 | }; 28 | 29 | 30 | 31 | int main() 32 | { 33 | Originator orginator; 34 | 35 | //捕获对象状态,存储到备忘录 36 | Memento mem = orginator.createMomento(); 37 | 38 | //... 改变orginator状态 39 | 40 | //从备忘录中恢复 41 | orginator.setMomento(memento); 42 | 43 | 44 | 45 | } -------------------------------------------------------------------------------- /Strategy-Pattern/main.cpp: -------------------------------------------------------------------------------- 1 | #include "MallardDuck.hpp" 2 | #include "RedHeadDuck.hpp" 3 | #include "DecoyDuck.hpp" 4 | #include "RubberDuck.hpp" 5 | 6 | #include 7 | 8 | int main() { 9 | MallardDuck mallard; 10 | mallard.display(); 11 | mallard.swim(); 12 | mallard.performQuack(); 13 | mallard.performFly(); 14 | 15 | std::cout << std::endl; 16 | 17 | RedHeadDuck redHead; 18 | redHead.display(); 19 | redHead.swim(); 20 | redHead.performQuack(); 21 | redHead.performFly(); 22 | 23 | std::cout << std::endl; 24 | 25 | DecoyDuck decoy; 26 | decoy.display(); 27 | decoy.swim(); 28 | decoy.performQuack(); 29 | decoy.performFly(); 30 | 31 | std::cout << std::endl; 32 | 33 | RubberDuck rubberDuckie; 34 | rubberDuckie.display(); 35 | rubberDuckie.swim(); 36 | rubberDuckie.performQuack(); 37 | rubberDuckie.performFly(); 38 | 39 | std::cout << std::endl; 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Observer-Pattern/WeatherData.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WEATHERDATA_HPP 2 | #define WEATHERDATA_HPP 3 | 4 | #include "Subject.hpp" 5 | #include "Observer.hpp" 6 | 7 | #include 8 | 9 | class WeatherData : public Subject { 10 | private: 11 | std::unordered_set observers; 12 | float temperature; 13 | float humidity; 14 | float pressure; 15 | public: 16 | void registerObserver(Observer* o) { 17 | observers.insert(o); 18 | } 19 | 20 | void removeObserver(Observer* o) { 21 | observers.erase(o); 22 | } 23 | 24 | void notifyObservers() { 25 | for(auto o : observers) { 26 | o->update(temperature, humidity, pressure); 27 | } 28 | } 29 | 30 | void measurementsChanged() { 31 | notifyObservers(); 32 | } 33 | 34 | void setMeasurements(float t, float h, float p) { 35 | temperature = t; 36 | humidity = h; 37 | pressure = p; 38 | measurementsChanged(); 39 | } 40 | }; 41 | 42 | #endif -------------------------------------------------------------------------------- /Factory Method/FileSplitter2.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | //具体类 4 | class BinarySplitter : public ISplitter{ 5 | 6 | }; 7 | 8 | class TxtSplitter: public ISplitter{ 9 | 10 | }; 11 | 12 | class PictureSplitter: public ISplitter{ 13 | 14 | }; 15 | 16 | class VideoSplitter: public ISplitter{ 17 | 18 | }; 19 | 20 | //具体工厂 21 | class BinarySplitterFactory: public SplitterFactory{ 22 | public: 23 | virtual ISplitter* CreateSplitter(){ 24 | return new BinarySplitter(); 25 | } 26 | }; 27 | 28 | class TxtSplitterFactory: public SplitterFactory{ 29 | public: 30 | virtual ISplitter* CreateSplitter(){ 31 | return new TxtSplitter(); 32 | } 33 | }; 34 | 35 | class PictureSplitterFactory: public SplitterFactory{ 36 | public: 37 | virtual ISplitter* CreateSplitter(){ 38 | return new PictureSplitter(); 39 | } 40 | }; 41 | 42 | class VideoSplitterFactory: public SplitterFactory{ 43 | public: 44 | virtual ISplitter* CreateSplitter(){ 45 | return new VideoSplitter(); 46 | } 47 | }; 48 | 49 | -------------------------------------------------------------------------------- /Observer-Pattern/CurrentConditionsDisplay.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CURRENTCONDITIONSDISPLAY_HPP 2 | #define CURRENTCONDITIONSDISPLAY_HPP 3 | 4 | #include "Observer.hpp" 5 | #include "DisplayElement.hpp" 6 | 7 | #include 8 | #include 9 | 10 | class CurrentConditionsDisplay : public Observer, public DisplayElement { 11 | private: 12 | float temperature; 13 | float humidity; 14 | std::shared_ptr weatherData; 15 | public: 16 | CurrentConditionsDisplay(std::shared_ptr w) : 17 | temperature(0.0f), humidity(0.0f), weatherData(std::move(w)) { 18 | } 19 | 20 | void registerObserver() { 21 | weatherData->registerObserver(this); 22 | } 23 | 24 | ~CurrentConditionsDisplay() { 25 | weatherData->registerObserver(this); 26 | } 27 | 28 | void update(float t, float h, float p) { 29 | temperature = t; 30 | humidity = h; 31 | display(); 32 | } 33 | 34 | void display() { 35 | std::cout << "Current condidions: " << temperature << "F degrees and " 36 | << humidity << "% humidity" << std::endl; 37 | } 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Iterator/Iterator.cpp: -------------------------------------------------------------------------------- 1 | template 2 | class Iterator 3 | { 4 | public: 5 | virtual void first() = 0; 6 | virtual void next() = 0; 7 | virtual bool isDone() const = 0; 8 | virtual T& current() = 0; 9 | }; 10 | 11 | 12 | 13 | template 14 | class MyCollection{ 15 | 16 | public: 17 | 18 | Iterator GetIterator(){ 19 | //... 20 | } 21 | 22 | }; 23 | 24 | template 25 | class CollectionIterator : public Iterator{ 26 | MyCollection mc; 27 | public: 28 | 29 | CollectionIterator(const MyCollection & c): mc(c){ } 30 | 31 | void first() override { 32 | 33 | } 34 | void next() override { 35 | 36 | } 37 | bool isDone() const override{ 38 | 39 | } 40 | T& current() override{ 41 | 42 | } 43 | }; 44 | 45 | void MyAlgorithm() 46 | { 47 | MyCollection mc; 48 | 49 | Iterator iter= mc.GetIterator(); 50 | 51 | for (iter.first(); !iter.isDone(); iter.next()){ 52 | cout << iter.current() << endl; 53 | } 54 | 55 | } 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Adapter/Adapter.cpp: -------------------------------------------------------------------------------- 1 | //目标接口(新接口) 2 | class ITarget{ 3 | public: 4 | virtual void process()=0; 5 | }; 6 | 7 | //遗留接口(老接口) 8 | class IAdaptee{ 9 | public: 10 | virtual void foo(int data)=0; 11 | virtual int bar()=0; 12 | }; 13 | 14 | //遗留类型 15 | class OldClass: public IAdaptee{ 16 | //.... 17 | }; 18 | 19 | //对象适配器 20 | class Adapter: public ITarget{ //继承 21 | protected: 22 | IAdaptee* pAdaptee;//组合 23 | 24 | public: 25 | 26 | Adapter(IAdaptee* pAdaptee){ 27 | this->pAdaptee=pAdaptee; 28 | } 29 | 30 | virtual void process(){ 31 | int data=pAdaptee->bar(); 32 | pAdaptee->foo(data); 33 | 34 | } 35 | 36 | 37 | }; 38 | 39 | 40 | //类适配器 41 | class Adapter: public ITarget, 42 | protected OldClass{ //多继承 43 | 44 | 45 | } 46 | 47 | 48 | int main(){ 49 | IAdaptee* pAdaptee=new OldClass(); 50 | 51 | 52 | ITarget* pTarget=new Adapter(pAdaptee); 53 | pTarget->process(); 54 | 55 | 56 | } 57 | 58 | 59 | class stack{ 60 | deqeue container; 61 | 62 | }; 63 | 64 | class queue{ 65 | deqeue container; 66 | 67 | }; 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /State/state1.cpp: -------------------------------------------------------------------------------- 1 | enum NetworkState 2 | { 3 | Network_Open, 4 | Network_Close, 5 | Network_Connect, 6 | }; 7 | 8 | class NetworkProcessor{ 9 | 10 | NetworkState state; 11 | 12 | public: 13 | 14 | void Operation1(){ 15 | if (state == Network_Open){ 16 | 17 | //********** 18 | state = Network_Close; 19 | } 20 | else if (state == Network_Close){ 21 | 22 | //.......... 23 | state = Network_Connect; 24 | } 25 | else if (state == Network_Connect){ 26 | 27 | //$$$$$$$$$$ 28 | state = Network_Open; 29 | } 30 | } 31 | 32 | public void Operation2(){ 33 | 34 | if (state == Network_Open){ 35 | 36 | //********** 37 | state = Network_Connect; 38 | } 39 | else if (state == Network_Close){ 40 | 41 | //..... 42 | state = Network_Open; 43 | } 44 | else if (state == Network_Connect){ 45 | 46 | //$$$$$$$$$$ 47 | state = Network_Close; 48 | } 49 | 50 | } 51 | 52 | public void Operation3(){ 53 | 54 | } 55 | }; 56 | 57 | 58 | -------------------------------------------------------------------------------- /Command/Command.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | 7 | class Command 8 | { 9 | public: 10 | virtual void execute() = 0; 11 | }; 12 | 13 | class ConcreteCommand1 : public Command 14 | { 15 | string arg; 16 | public: 17 | ConcreteCommand1(const string & a) : arg(a) {} 18 | void execute() override 19 | { 20 | cout<< "#1 process..."< commands; 39 | public: 40 | void addCommand(Command *c) { commands.push_back(c); } 41 | void execute() override 42 | { 43 | for (auto &c : commands) 44 | { 45 | c->execute(); 46 | } 47 | } 48 | }; 49 | 50 | 51 | 52 | int main() 53 | { 54 | 55 | ConcreteCommand1 command1(receiver, "Arg ###"); 56 | ConcreteCommand2 command2(receiver, "Arg $$$"); 57 | 58 | MacroCommand macro; 59 | macro.addCommand(&command1); 60 | macro.addCommand(&command2); 61 | 62 | macro.execute(); 63 | 64 | } -------------------------------------------------------------------------------- /Builder/builder.cpp: -------------------------------------------------------------------------------- 1 | 2 | class House{ 3 | //.... 4 | }; 5 | 6 | class HouseBuilder { 7 | public: 8 | House* GetResult(){ 9 | return pHouse; 10 | } 11 | virtual ~HouseBuilder(){} 12 | protected: 13 | 14 | House* pHouse; 15 | virtual void BuildPart1()=0; 16 | virtual void BuildPart2()=0; 17 | virtual void BuildPart3()=0; 18 | virtual void BuildPart4()=0; 19 | virtual void BuildPart5()=0; 20 | 21 | }; 22 | 23 | class StoneHouse: public House{ 24 | 25 | }; 26 | 27 | class StoneHouseBuilder: public HouseBuilder{ 28 | protected: 29 | 30 | virtual void BuildPart1(){ 31 | //pHouse->Part1 = ...; 32 | } 33 | virtual void BuildPart2(){ 34 | 35 | } 36 | virtual void BuildPart3(){ 37 | 38 | } 39 | virtual void BuildPart4(){ 40 | 41 | } 42 | virtual void BuildPart5(){ 43 | 44 | } 45 | 46 | }; 47 | 48 | 49 | class HouseDirector{ 50 | 51 | public: 52 | HouseBuilder* pHouseBuilder; 53 | 54 | HouseDirector(HouseBuilder* pHouseBuilder){ 55 | this->pHouseBuilder=pHouseBuilder; 56 | } 57 | 58 | House* Construct(){ 59 | 60 | pHouseBuilder->BuildPart1(); 61 | 62 | for (int i = 0; i < 4; i++){ 63 | pHouseBuilder->BuildPart2(); 64 | } 65 | 66 | bool flag=pHouseBuilder->BuildPart3(); 67 | 68 | if(flag){ 69 | pHouseBuilder->BuildPart4(); 70 | } 71 | 72 | pHouseBuilder->BuildPart5(); 73 | 74 | return pHouseBuilder->GetResult(); 75 | } 76 | }; 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /Abstract Factory/EmployeeDAO3.cpp: -------------------------------------------------------------------------------- 1 | 2 | //数据库访问有关的基类 3 | class IDBConnection{ 4 | 5 | }; 6 | 7 | class IDBCommand{ 8 | 9 | }; 10 | 11 | class IDataReader{ 12 | 13 | }; 14 | 15 | 16 | class IDBFactory{ 17 | public: 18 | virtual IDBConnection* CreateDBConnection()=0; 19 | virtual IDBCommand* CreateDBCommand()=0; 20 | virtual IDataReader* CreateDataReader()=0; 21 | 22 | }; 23 | 24 | 25 | //支持SQL Server 26 | class SqlConnection: public IDBConnection{ 27 | 28 | }; 29 | class SqlCommand: public IDBCommand{ 30 | 31 | }; 32 | class SqlDataReader: public IDataReader{ 33 | 34 | }; 35 | 36 | 37 | class SqlDBFactory:public IDBFactory{ 38 | public: 39 | virtual IDBConnection* CreateDBConnection()=0; 40 | virtual IDBCommand* CreateDBCommand()=0; 41 | virtual IDataReader* CreateDataReader()=0; 42 | 43 | }; 44 | 45 | //支持Oracle 46 | class OracleConnection: public IDBConnection{ 47 | 48 | }; 49 | 50 | class OracleCommand: public IDBCommand{ 51 | 52 | }; 53 | 54 | class OracleDataReader: public IDataReader{ 55 | 56 | }; 57 | 58 | 59 | 60 | class EmployeeDAO{ 61 | IDBFactory* dbFactory; 62 | 63 | public: 64 | vector GetEmployees(){ 65 | IDBConnection* connection = 66 | dbFactory->CreateDBConnection(); 67 | connection->ConnectionString("..."); 68 | 69 | IDBCommand* command = 70 | dbFactory->CreateDBCommand(); 71 | command->CommandText("..."); 72 | command->SetConnection(connection); //关联性 73 | 74 | IDBDataReader* reader = command->ExecuteReader(); //关联性 75 | while (reader->Read()){ 76 | 77 | } 78 | 79 | } 80 | }; 81 | -------------------------------------------------------------------------------- /State/state2.cpp: -------------------------------------------------------------------------------- 1 | class NetworkState{ 2 | 3 | public: 4 | NetworkState* pNext; 5 | virtual void Operation1()=0; 6 | virtual void Operation2()=0; 7 | virtual void Operation3()=0; 8 | 9 | virtual ~NetworkState(){} 10 | }; 11 | 12 | 13 | class OpenState :public NetworkState{ 14 | 15 | static NetworkState* m_instance; 16 | public: 17 | static NetworkState* getInstance(){ 18 | if (m_instance == nullptr) { 19 | m_instance = new OpenState(); 20 | } 21 | return m_instance; 22 | } 23 | 24 | void Operation1(){ 25 | 26 | //********** 27 | pNext = CloseState::getInstance(); 28 | } 29 | 30 | void Operation2(){ 31 | 32 | //.......... 33 | pNext = ConnectState::getInstance(); 34 | } 35 | 36 | void Operation3(){ 37 | 38 | //$$$$$$$$$$ 39 | pNext = OpenState::getInstance(); 40 | } 41 | 42 | 43 | }; 44 | 45 | class CloseState:public NetworkState{ } 46 | //... 47 | 48 | 49 | class NetworkProcessor{ 50 | 51 | NetworkState* pState; 52 | 53 | public: 54 | 55 | NetworkProcessor(NetworkState* pState){ 56 | 57 | this->pState = pState; 58 | } 59 | 60 | void Operation1(){ 61 | //... 62 | pState->Operation1(); 63 | pState = pState->pNext; 64 | //... 65 | } 66 | 67 | void Operation2(){ 68 | //... 69 | pState->Operation2(); 70 | pState = pState->pNext; 71 | //... 72 | } 73 | 74 | void Operation3(){ 75 | //... 76 | pState->Operation3(); 77 | pState = pState->pNext; 78 | //... 79 | } 80 | 81 | }; 82 | 83 | 84 | -------------------------------------------------------------------------------- /Factory-Pattern/Pizza.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PIZZA_HPP 2 | #define PIZZA_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Pizza { 10 | public: 11 | std::string name; 12 | std::string dough; 13 | std::string sauce; 14 | std::vector toppings; 15 | 16 | const std::string& getName() const; 17 | 18 | virtual void prepare() const; 19 | virtual void bake() const; 20 | virtual void cut() const; 21 | virtual void box() const; 22 | virtual ~Pizza() = default; 23 | }; 24 | 25 | const std::string& Pizza::getName() const 26 | { 27 | return this->name; 28 | } 29 | 30 | void Pizza::prepare() const 31 | { 32 | std::cout << "Preparing " + getName() << std::endl; 33 | std::cout << "Tossing dough..." << std::endl; 34 | std::cout << "Adding sauce..." << std::endl; 35 | std::cout << "Adding toppings: " << std::endl; 36 | for (auto& topping : this->toppings) 37 | { 38 | std::cout << " " + topping + "\n"; 39 | } 40 | } 41 | void Pizza::bake() const 42 | { 43 | std::cout << "Baking for 25 min at 350 degrees "<< std::endl; 44 | } 45 | 46 | void Pizza::cut() const 47 | { 48 | std::cout << "Cut the pizza into diagonal slices "<< std::endl; 49 | } 50 | void Pizza::box() const 51 | { 52 | std::cout << "Boxing in official PizzaStore boxes" << std::endl; 53 | } 54 | 55 | std::ostream& operator<<(std::ostream& os, const Pizza& pizza) 56 | { 57 | std::string str; 58 | 59 | str = "\n---- " + pizza.getName() + "----\n"; 60 | str.append(pizza.dough + "\n"); 61 | str.append(pizza.sauce + "\n"); 62 | 63 | for (auto& topping : pizza.toppings) 64 | { 65 | str.append(" " + topping + "\n"); 66 | } 67 | 68 | str.append("\n"); 69 | 70 | return os << str; 71 | } 72 | 73 | #endif -------------------------------------------------------------------------------- /Singleton/Singleton.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton{ 4 | private: 5 | Singleton(); 6 | Singleton(const Singleton& other); 7 | public: 8 | static Singleton* getInstance(); 9 | static Singleton* m_instance; 10 | }; 11 | 12 | Singleton* Singleton::m_instance=nullptr; 13 | 14 | //线程非安全版本 15 | Singleton* Singleton::getInstance() { 16 | if (m_instance == nullptr) { 17 | m_instance = new Singleton(); 18 | } 19 | return m_instance; 20 | } 21 | 22 | 23 | 24 | 25 | 26 | 27 | //线程安全版本,但锁的代价过高 28 | Singleton* Singleton::getInstance() { 29 | Lock lock; 30 | if (m_instance == nullptr) { 31 | m_instance = new Singleton(); 32 | } 33 | return m_instance; 34 | } 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | //双检查锁,但由于内存读写reorder不安全 45 | Singleton* Singleton::getInstance() { 46 | 47 | if(m_instance==nullptr){ 48 | Lock lock; 49 | if (m_instance == nullptr) { 50 | m_instance = new Singleton(); 51 | } 52 | } 53 | return m_instance; 54 | } 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | //C++ 11版本之后的跨平台实现 (volatile) 64 | std::atomic Singleton::m_instance; 65 | std::mutex Singleton::m_mutex; 66 | 67 | Singleton* Singleton::getInstance() { 68 | Singleton* tmp = m_instance.load(std::memory_order_relaxed); 69 | std::atomic_thread_fence(std::memory_order_acquire);//获取内存fence 70 | if (tmp == nullptr) { 71 | std::lock_guard lock(m_mutex); 72 | tmp = m_instance.load(std::memory_order_relaxed); 73 | if (tmp == nullptr) { 74 | tmp = new Singleton; 75 | std::atomic_thread_fence(std::memory_order_release);//释放内存fence 76 | m_instance.store(tmp, std::memory_order_relaxed); 77 | } 78 | } 79 | return tmp; 80 | } 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Composite/composite.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class Component 9 | { 10 | public: 11 | virtual void process() = 0; 12 | virtual ~Component(){} 13 | }; 14 | 15 | //树节点 16 | class Composite : public Component{ 17 | 18 | string name; 19 | list elements; 20 | public: 21 | Composite(const string & s) : name(s) {} 22 | 23 | void add(Component* element) { 24 | elements.push_back(element); 25 | } 26 | void remove(Component* element){ 27 | elements.remove(element); 28 | } 29 | 30 | void process(){ 31 | 32 | //1. process current node 33 | 34 | 35 | //2. process leaf nodes 36 | for (auto &e : elements) 37 | e->process(); //多态调用 38 | 39 | } 40 | }; 41 | 42 | //叶子节点 43 | class Leaf : public Component{ 44 | string name; 45 | public: 46 | Leaf(string s) : name(s) {} 47 | 48 | void process(){ 49 | //process current node 50 | } 51 | }; 52 | 53 | 54 | void Invoke(Component & c){ 55 | //... 56 | c.process(); 57 | //... 58 | } 59 | 60 | 61 | int main() 62 | { 63 | 64 | Composite root("root"); 65 | Composite treeNode1("treeNode1"); 66 | Composite treeNode2("treeNode2"); 67 | Composite treeNode3("treeNode3"); 68 | Composite treeNode4("treeNode4"); 69 | Leaf leat1("left1"); 70 | Leaf leat2("left2"); 71 | 72 | root.add(&treeNode1); 73 | treeNode1.add(&treeNode2); 74 | treeNode2.add(&leaf1); 75 | 76 | root.add(&treeNode3); 77 | treeNode3.add(&treeNode4); 78 | treeNode4.add(&leaf2); 79 | 80 | process(root); 81 | process(leaf2); 82 | process(treeNode3); 83 | 84 | } -------------------------------------------------------------------------------- /Visitor/Visitor1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Visitor; 5 | 6 | 7 | class Element 8 | { 9 | public: 10 | virtual void accept(Visitor& visitor) = 0; //第一次多态辨析 11 | 12 | virtual ~Element(){} 13 | }; 14 | 15 | class ElementA : public Element 16 | { 17 | public: 18 | void accept(Visitor &visitor) override { 19 | visitor.visitElementA(*this); 20 | } 21 | 22 | 23 | }; 24 | 25 | class ElementB : public Element 26 | { 27 | public: 28 | void accept(Visitor &visitor) override { 29 | visitor.visitElementB(*this); //第二次多态辨析 30 | } 31 | 32 | }; 33 | 34 | 35 | class Visitor{ 36 | public: 37 | virtual void visitElementA(ElementA& element) = 0; 38 | virtual void visitElementB(ElementB& element) = 0; 39 | 40 | virtual ~Visitor(){} 41 | }; 42 | 43 | //================================== 44 | 45 | //扩展1 46 | class Visitor1 : public Visitor{ 47 | public: 48 | void visitElementA(ElementA& element) override{ 49 | cout << "Visitor1 is processing ElementA" << endl; 50 | } 51 | 52 | void visitElementB(ElementB& element) override{ 53 | cout << "Visitor1 is processing ElementB" << endl; 54 | } 55 | }; 56 | 57 | //扩展2 58 | class Visitor2 : public Visitor{ 59 | public: 60 | void visitElementA(ElementA& element) override{ 61 | cout << "Visitor2 is processing ElementA" << endl; 62 | } 63 | 64 | void visitElementB(ElementB& element) override{ 65 | cout << "Visitor2 is processing ElementB" << endl; 66 | } 67 | }; 68 | 69 | 70 | 71 | 72 | int main() 73 | { 74 | Visitor2 visitor; 75 | ElementB elementB; 76 | elementB.accept(visitor);// double dispatch 77 | 78 | ElementA elementA; 79 | elementA.accept(visitor); 80 | 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /Abstract Factory/EmployeeDAO2.cpp: -------------------------------------------------------------------------------- 1 | 2 | //数据库访问有关的基类 3 | class IDBConnection{ 4 | 5 | }; 6 | class IDBConnectionFactory{ 7 | public: 8 | virtual IDBConnection* CreateDBConnection()=0; 9 | }; 10 | 11 | 12 | class IDBCommand{ 13 | 14 | }; 15 | class IDBCommandFactory{ 16 | public: 17 | virtual IDBCommand* CreateDBCommand()=0; 18 | }; 19 | 20 | 21 | class IDataReader{ 22 | 23 | }; 24 | class IDataReaderFactory{ 25 | public: 26 | virtual IDataReader* CreateDataReader()=0; 27 | }; 28 | 29 | 30 | //支持SQL Server 31 | class SqlConnection: public IDBConnection{ 32 | 33 | }; 34 | class SqlConnectionFactory:public IDBConnectionFactory{ 35 | 36 | }; 37 | 38 | 39 | class SqlCommand: public IDBCommand{ 40 | 41 | }; 42 | class SqlCommandFactory:public IDBCommandFactory{ 43 | 44 | }; 45 | 46 | 47 | class SqlDataReader: public IDataReader{ 48 | 49 | }; 50 | class SqlDataReaderFactory:public IDataReaderFactory{ 51 | 52 | }; 53 | 54 | //支持Oracle 55 | class OracleConnection: public IDBConnection{ 56 | 57 | }; 58 | 59 | class OracleCommand: public IDBCommand{ 60 | 61 | }; 62 | 63 | class OracleDataReader: public IDataReader{ 64 | 65 | }; 66 | 67 | 68 | 69 | class EmployeeDAO{ 70 | IDBConnectionFactory* dbConnectionFactory; 71 | IDBCommandFactory* dbCommandFactory; 72 | IDataReaderFactory* dataReaderFactory; 73 | 74 | 75 | public: 76 | vector GetEmployees(){ 77 | IDBConnection* connection = 78 | dbConnectionFactory->CreateDBConnection(); 79 | connection->ConnectionString("..."); 80 | 81 | IDBCommand* command = 82 | dbCommandFactory->CreateDBCommand(); 83 | command->CommandText("..."); 84 | command->SetConnection(connection); //关联性 85 | 86 | IDBDataReader* reader = command->ExecuteReader(); //关联性 87 | while (reader->Read()){ 88 | 89 | } 90 | 91 | } 92 | }; 93 | -------------------------------------------------------------------------------- /Decorator/decorator2.cpp: -------------------------------------------------------------------------------- 1 | //业务操作 2 | class Stream{ 3 | 4 | public: 5 | virtual char Read(int number)=0; 6 | virtual void Seek(int position)=0; 7 | virtual void Write(char data)=0; 8 | 9 | virtual ~Stream(){} 10 | }; 11 | 12 | //主体类 13 | class FileStream: public Stream{ 14 | public: 15 | virtual char Read(int number){ 16 | //读文件流 17 | } 18 | virtual void Seek(int position){ 19 | //定位文件流 20 | } 21 | virtual void Write(char data){ 22 | //写文件流 23 | } 24 | 25 | }; 26 | 27 | class NetworkStream :public Stream{ 28 | public: 29 | virtual char Read(int number){ 30 | //读网络流 31 | } 32 | virtual void Seek(int position){ 33 | //定位网络流 34 | } 35 | virtual void Write(char data){ 36 | //写网络流 37 | } 38 | 39 | }; 40 | 41 | class MemoryStream :public Stream{ 42 | public: 43 | virtual char Read(int number){ 44 | //读内存流 45 | } 46 | virtual void Seek(int position){ 47 | //定位内存流 48 | } 49 | virtual void Write(char data){ 50 | //写内存流 51 | } 52 | 53 | }; 54 | 55 | //扩展操作 56 | 57 | // 三个子类变为一个子类,用组合代替继承 58 | class CryptoStream: public Stream { 59 | 60 | Stream* stream;//... 61 | 62 | public: 63 | CryptoStream(Stream* stm):stream(stm){ 64 | 65 | } 66 | 67 | 68 | virtual char Read(int number){ 69 | 70 | //额外的加密操作... 71 | stream->Read(number);//读文件流 72 | } 73 | virtual void Seek(int position){ 74 | //额外的加密操作... 75 | stream::Seek(position);//定位文件流 76 | //额外的加密操作... 77 | } 78 | virtual void Write(byte data){ 79 | //额外的加密操作... 80 | stream::Write(data);//写文件流 81 | //额外的加密操作... 82 | } 83 | }; 84 | 85 | 86 | 87 | class BufferedStream : public Stream{ 88 | 89 | Stream* stream;//... 90 | 91 | public: 92 | BufferedStream(Stream* stm):stream(stm){ 93 | 94 | } 95 | //... 96 | }; 97 | 98 | 99 | 100 | 101 | 102 | void Process(){ 103 | 104 | //运行时装配 105 | FileStream* s1=new FileStream(); 106 | CryptoStream* s2=new CryptoStream(s1); 107 | 108 | BufferedStream* s3=new BufferedStream(s1); 109 | 110 | BufferedStream* s4=new BufferedStream(s2); 111 | 112 | 113 | 114 | } -------------------------------------------------------------------------------- /Decorator/decorator3.cpp: -------------------------------------------------------------------------------- 1 | //业务操作 2 | class Stream{ 3 | 4 | public: 5 | virtual char Read(int number)=0; 6 | virtual void Seek(int position)=0; 7 | virtual void Write(char data)=0; 8 | 9 | virtual ~Stream(){} 10 | }; 11 | 12 | //主体类 13 | class FileStream: public Stream{ 14 | public: 15 | virtual char Read(int number){ 16 | //读文件流 17 | } 18 | virtual void Seek(int position){ 19 | //定位文件流 20 | } 21 | virtual void Write(char data){ 22 | //写文件流 23 | } 24 | 25 | }; 26 | 27 | class NetworkStream :public Stream{ 28 | public: 29 | virtual char Read(int number){ 30 | //读网络流 31 | } 32 | virtual void Seek(int position){ 33 | //定位网络流 34 | } 35 | virtual void Write(char data){ 36 | //写网络流 37 | } 38 | 39 | }; 40 | 41 | class MemoryStream :public Stream{ 42 | public: 43 | virtual char Read(int number){ 44 | //读内存流 45 | } 46 | virtual void Seek(int position){ 47 | //定位内存流 48 | } 49 | virtual void Write(char data){ 50 | //写内存流 51 | } 52 | 53 | }; 54 | 55 | //扩展操作 56 | 57 | // 由于两个子类有相同的成员Stream*,所以这个成员要往上提 58 | DecoratorStream: public Stream{ 59 | protected: 60 | Stream* stream;//... 61 | 62 | DecoratorStream(Stream * stm):stream(stm){ 63 | 64 | } 65 | 66 | }; 67 | 68 | class CryptoStream: public DecoratorStream { 69 | 70 | 71 | public: 72 | CryptoStream(Stream* stm):DecoratorStream(stm){ 73 | 74 | } 75 | 76 | 77 | virtual char Read(int number){ 78 | 79 | //额外的加密操作... 80 | stream->Read(number);//读文件流 81 | } 82 | virtual void Seek(int position){ 83 | //额外的加密操作... 84 | stream::Seek(position);//定位文件流 85 | //额外的加密操作... 86 | } 87 | virtual void Write(byte data){ 88 | //额外的加密操作... 89 | stream::Write(data);//写文件流 90 | //额外的加密操作... 91 | } 92 | }; 93 | 94 | 95 | 96 | class BufferedStream : public DecoratorStream{ 97 | 98 | Stream* stream;//... 99 | 100 | public: 101 | BufferedStream(Stream* stm):DecoratorStream(stm){ 102 | 103 | } 104 | //... 105 | }; 106 | 107 | 108 | 109 | 110 | void Process(){ 111 | 112 | //运行时装配 113 | FileStream* s1=new FileStream(); 114 | 115 | CryptoStream* s2=new CryptoStream(s1); 116 | 117 | BufferedStream* s3=new BufferedStream(s1); 118 | 119 | BufferedStream* s4=new BufferedStream(s2); 120 | 121 | 122 | 123 | } -------------------------------------------------------------------------------- /Chain of Resposibility/ChainofResposibility.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | enum class RequestType 7 | { 8 | REQ_HANDLER1, 9 | REQ_HANDLER2, 10 | REQ_HANDLER3 11 | }; 12 | 13 | class Reqest 14 | { 15 | string description; 16 | RequestType reqType; 17 | public: 18 | Reqest(const string & desc, RequestType type) : description(desc), reqType(type) {} 19 | RequestType getReqType() const { return reqType; } 20 | const string& getDescription() const { return description; } 21 | }; 22 | 23 | class ChainHandler{ 24 | 25 | ChainHandler *nextChain; 26 | void sendReqestToNextHandler(const Reqest & req) 27 | { 28 | if (nextChain != nullptr) 29 | nextChain->handle(req); 30 | } 31 | protected: 32 | virtual bool canHandleRequest(const Reqest & req) = 0; 33 | virtual void processRequest(const Reqest & req) = 0; 34 | public: 35 | ChainHandler() { nextChain = nullptr; } 36 | void setNextChain(ChainHandler *next) { nextChain = next; } 37 | 38 | 39 | void handle(const Reqest & req) 40 | { 41 | if (canHandleRequest(req)) 42 | processRequest(req); 43 | else 44 | sendReqestToNextHandler(req); 45 | } 46 | }; 47 | 48 | 49 | class Handler1 : public ChainHandler{ 50 | protected: 51 | bool canHandleRequest(const Reqest & req) override 52 | { 53 | return req.getReqType() == RequestType::REQ_HANDLER1; 54 | } 55 | void processRequest(const Reqest & req) override 56 | { 57 | cout << "Handler1 is handle reqest: " << req.getDescription() << endl; 58 | } 59 | }; 60 | 61 | class Handler2 : public ChainHandler{ 62 | protected: 63 | bool canHandleRequest(const Reqest & req) override 64 | { 65 | return req.getReqType() == RequestType::REQ_HANDLER2; 66 | } 67 | void processRequest(const Reqest & req) override 68 | { 69 | cout << "Handler2 is handle reqest: " << req.getDescription() << endl; 70 | } 71 | }; 72 | 73 | class Handler3 : public ChainHandler{ 74 | protected: 75 | bool canHandleRequest(const Reqest & req) override 76 | { 77 | return req.getReqType() == RequestType::REQ_HANDLER3; 78 | } 79 | void processRequest(const Reqest & req) override 80 | { 81 | cout << "Handler3 is handle reqest: " << req.getDescription() << endl; 82 | } 83 | }; 84 | 85 | int main(){ 86 | Handler1 h1; 87 | Handler2 h2; 88 | Handler3 h3; 89 | h1.setNextChain(&h2); 90 | h2.setNextChain(&h3); 91 | 92 | Reqest req("process task ... ", RequestType::REQ_HANDLER3); 93 | h1.handle(req); 94 | return 0; 95 | } -------------------------------------------------------------------------------- /Interpreter/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class Expression { 9 | public: 10 | virtual int interpreter(map var)=0; 11 | virtual ~Expression(){} 12 | }; 13 | 14 | //变量表达式 15 | class VarExpression: public Expression { 16 | 17 | char key; 18 | 19 | public: 20 | VarExpression(const char& key) 21 | { 22 | this->key = key; 23 | } 24 | 25 | int interpreter(map var) override { 26 | return var[key]; 27 | } 28 | 29 | }; 30 | 31 | //符号表达式 32 | class SymbolExpression : public Expression { 33 | 34 | // 运算符左右两个参数 35 | protected: 36 | Expression* left; 37 | Expression* right; 38 | 39 | public: 40 | SymbolExpression( Expression* left, Expression* right): 41 | left(left),right(right){ 42 | 43 | } 44 | 45 | }; 46 | 47 | //加法运算 48 | class AddExpression : public SymbolExpression { 49 | 50 | public: 51 | AddExpression(Expression* left, Expression* right): 52 | SymbolExpression(left,right){ 53 | 54 | } 55 | int interpreter(map var) override { 56 | return left->interpreter(var) + right->interpreter(var); 57 | } 58 | 59 | }; 60 | 61 | //减法运算 62 | class SubExpression : public SymbolExpression { 63 | 64 | public: 65 | SubExpression(Expression* left, Expression* right): 66 | SymbolExpression(left,right){ 67 | 68 | } 69 | int interpreter(map var) override { 70 | return left->interpreter(var) - right->interpreter(var); 71 | } 72 | 73 | }; 74 | 75 | 76 | 77 | Expression* analyse(string expStr) { 78 | 79 | stack expStack; 80 | Expression* left = nullptr; 81 | Expression* right = nullptr; 82 | for(int i=0; i var; 119 | var.insert(make_pair('a',5)); 120 | var.insert(make_pair('b',2)); 121 | var.insert(make_pair('c',1)); 122 | var.insert(make_pair('d',6)); 123 | var.insert(make_pair('e',10)); 124 | 125 | 126 | Expression* expression= analyse(expStr); 127 | 128 | int result=expression->interpreter(var); 129 | 130 | cout<