Categories
程式開發

一文學會設計模式



{“ type”:“ doc”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:0,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”最近在研究设计模式,发现尽管设计模式是针对面向对象语言提出的,但貌似市面上大多数都是基于java给出的例子,C++的例子极少,自己看完李建忠老师的GOF设计模式视频后查阅各种资料并结合自身实践总结如下,希望对大家有所帮助。”}]},{“ type”:“標題”,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”设计模式简介”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”设计模式是主要针对面向对象语言提出的一种设计思想,主要是提高代码可复用性,抵御变化,尽量将变化所带来的影响降到最低。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”面向对象特点”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ bulletedlist” ,“內容”:[{“type”:”listitem”,”content”:[{“type”:”paragraph”,”content”:[{“type”:”text”,”text”:”封装:隐藏内部实现”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”content”:[{“type”:”text”,”text”:”继承:复用现有的代码”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”content”:[{“type”:”text”,”text”:”多态:改写对象的行为”}]}]}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”面向对象设计原则”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ numberedlist” ,“ attrs”:{“ start”:1,“ normalizeStart”:1},“ content”:[{“type”:”listitem”,”content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:1,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”依赖倒置原则:针对接口编程,依赖于抽象而不依赖于具体,抽象(稳定)不应依赖于实现细节(变化),实现细节应该依赖于抽象,因为稳定态如果依赖于变化态则会变成不稳定态。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:2,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”开放封闭原则:对扩展开放,对修改关闭,业务需求是不断变化的,当程序需要扩展的时候,不要去修改原来的代码,而要灵活使用抽象和继承,增加程序的扩展性,使易于维护和升级,类、模块、函数等都是可以扩展的,但是不可修改。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:3,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”单一职责原则:一个类只做一件事,一个类应该仅有一个引起它变化的原因,并且变化的方向隐含着类的责任。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:4,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”里氏替换原则:子类必须能够替换父类,任何引用基类的地方必须能透明的使用其子类的对象,开放关闭原则的具体实现手段之一。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:5,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”接口隔离原则:接口最小化且完备,尽量少public来减少对外交互,只把外部需要的方法暴露出来。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:6,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”最少知道原则:一个实体应该尽可能少的与其他实体发生相互作用。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:7,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”将变化的点进行封装,做好分界,保持一侧变化,一侧稳定,调用侧永远稳定,被调用测内部可以变化。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:8,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”优先使用组合而非继承,继承为白箱操作,而组合为黑箱,继承某种程度上破坏了封装性,而且父类与子类之间耦合度比较高。”}]}]},{“ type”:“ listitem”,“ content”:[{“type”:”paragraph”,”attrs”:{“indent”:0,”number”:9,”align”:null,”origin”:null},”content”:[{“type”:”text”,”text”:”针对接口编程,而非针对实现编程,强调”},{“type”:”text”,”marks”:[{“type”:”strong”}],“ text”:“接口標準化”},{“ type”:“ text”,“ text”:“。”}]}]}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”小总结: 没有一步到位的设计模式,刚开始编程时不要把太多精力放到设计模式上,需求总是变化的,刚开始着重于实现,一般敏捷开发后为了应对变化重构再决定采取合适的设计模式。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”模板方法”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”父类定义算法的骨架,而将一些步骤延迟到子类去实现,使得子类可以复用骨架,并附加特性,以开发框架举例,框架开发人员把框架调用流程定好,而将某些具体的步骤作为虚函数留给子类去重写,话不多说,上代码。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef GAMEn#define GAMEnn#include nnclass Game {n public:n Game() {}nn virtual ~Game() {}nn void Run() {n InitGame();n StartGame();n StopGame();n }nn protected:n virtual void StartGame() { std::cout << "step 2: start game" << std::endl; }nn private:n void InitGame() { std::cout << "step 1: init game" << std::endl; }n void StopGame() { std::cout << "step 3: stop game" << std::endl; }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#include "game.h"nnclass BasketBall : public Game {n void StartGame() override { std::cout << "start basketball game" << std::endl; }n};"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:“text”,“text”:“#include”gameh“nnclassSocketBall:公共遊戲{nvoidStartGame()覆蓋{std::cout<<”start棒球遊戲“[{"type":"text""text":"#include"gameh"nnclassSocketBall:publicGame{nvoidStartGame()override{std::cout<<"startsocketballgame"[{“type”:“text”,“text”:“#include”gameh“nnclassSocketBall:公共遊戲{nvoidStartGame()覆蓋{std::cout<<”start棒球遊戲“[{"type":"text""text":"#include"gameh"nnclassSocketBall:publicGame{nvoidStartGame()override{std::cout<<"startsocketballgame"Run(); n刪除game2; n返回0; n} ng ++ test.cc -std = c ++ 11 && ./a.outn輸出: n步驟1:開始比賽 n開始籃球比賽 nstep 3:停止遊戲 nstep 1:初始化遊戲 n啟動套接字遊戲 nstep 3:停止遊戲“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”代码很简单,体现的是思想,游戏包含三个步骤,初始化游戏,开始游戏,停止游戏,初始化游戏和停止游戏步骤比较统一,由父类Game定义好,而开始游戏是第二个步骤,可以有打篮球和踢足球,将来也可以有羽毛球,乒乓球等等,每增加一项运动,都可以从Game父类中继承后重写开始游戏这个函数,达到不同的功能,符合”},{“type”:”text”,”marks”:[{“type”:”strong”}],“ text”:“模板方法”},{“ type”:“ text”,“ text”:“的特性,即”},{“ type”:“ text”,“ marks”:[{“type”:”strong”}],“ text”:“如何在確定穩定的結構下,應對子步驟需求的變化”},{“ type”:“ text”,“ text”:“。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”策略模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”定义一系列的算法,将它们一个个封装,使得他们可以相互替换,一般为了解决多个if-else带来的复杂性,在多种算法相似的情况下,通过策略模式可减少if-else带来的复杂性和难以维护性,一般在项目中发现多个if-else并且预感将来还会在此增加if-else分支,那基本上就需要使用策略模式。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”先举一个不使用策略模式的例子,拿计算来说,下面代码定义了加法操作和减法操作,以后如果需要增加乘法除法等计算,那就需要在枚举里添加新类型,并且增加if-else分支,这违反了开放关闭原则。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”enum class CalOperation {n add,n subn};nnint NoStragegy(CalOperation ope) {n if (ope == CalOperation::add) {n std::cout << "this is add operation" << std::endl;n } else if (ope == CalOperation::sub) {n std::cout << "this is sub operation" << std::endl;n } // 如何将来需要增加乘法或者除法或者其它运算,还需要增加if-elsen return 0;n}"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{"type":"text","text":"下例为使用策略模式,定义一个基类Calculation,包含虚函数operation()。"}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#ifndef CALCULATIONn#define CALCULATIONnn#include nnclass Calculation {n public:n Calculation() {}nn virtual ~Calculation() {}nn virtual void operation() { std::cout << "base operation" << std::endl; }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{"type":"text","text":"每增加一种运算,就增加一个继承基类的子类,重写operation()函数。"}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#ifndef ADDn#define ADDnn#include "calculation.h"nnclass Add : public Calculation {n void operation() override { std::cout << "this is add operation" << std::endl; }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:“text”,“text”:“#ifndefSUBn#defineSUBnn#include”calculationh“nnclassSub:publicCalculation{nvoidoperation()覆蓋{std::cout<<“這是子操作”[{"type":"text""text":"#ifndefSUBn#defineSUBnn#include"calculationh"nnclassSub:publicCalculation{nvoidoperation()override{std::cout<<"thisissuboperation"[{“type”:“text”,“text”:“#ifndefSUBn#defineSUBnn#include”calculationh“nnclassSub:publicCalculation{nvoidoperation()覆蓋{std::cout<<“這是子操作”[{"type":"text""text":"#ifndefSUBn#defineSUBnn#include"calculationh"nnclassSub:publicCalculation{nvoidoperation()override{std::cout<<"thisissuboperation"operation(); n刪除cal2; n n返回0; n}“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”是不是方便了很多,将来如果有乘法除法和其它运算规则,只需要再加一个继承基类的子类即可。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”观察者模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”定义对象间的一对多关系,当一个对象状态发生改变的时候,其它依赖于它的对象都会得到广播通知并进行自定义动作,通过面向对象技术的多态技术,可以降低这种依赖关系,降低耦合度,上代码.”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef OBSERVERn#define OBSERVERnn#include nnclass ObserverBase {n public:n ObserverBase() {}n virtual ~ObserverBase() {}nn virtual void Update() {}n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef _OBSERVERFIRSTCHILDn#define OBSERVERFIRSTCHILD_nn#include “observer.h”nnclass ObserverFirstChild : public ObserverBase {n void Update() override {n std::cout << "first child receive notify" << std::endl;n }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:“text”,“text”:“#ifndef_OBSERVERSECONDCHILDn#defineOBSERVERSECONDCHILD_nn#include”observerh“nnclassObserverSecondChild:publicObserverBase{nvoidUpdate()覆蓋{nstd::cout<<“第二個孩子收到通知”<[{"type":"text""text":"#ifndef_OBSERVERSECONDCHILDn#defineOBSERVERSECONDCHILD_nn#include"observerh"nnclassObserverSecondChild:publicObserverBase{nvoidUpdate()override{nstd::cout<<"secondchildreceivenotify"<[{“type”:“text”,“text”:“#ifndef_OBSERVERSECONDCHILDn#defineOBSERVERSECONDCHILD_nn#include”observerh“nnclassObserverSecondChild:publicObserverBase{nvoidUpdate()覆蓋{nstd::cout<<“第二個孩子收到通知”<[{"type":"text""text":"#ifndef_OBSERVERSECONDCHILDn#defineOBSERVERSECONDCHILD_nn#include"observerh"nnclassObserverSecondChild:publicObserverBase{nvoidUpdate()override{nstd::cout<<"secondchildreceivenotify"<< std::endl;n }n};nn#endif"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"#include n#include "observerfirstchild.h"n#include "observersecondchild.h"nnclass NotifyBase {n public:n void Add(ObserverBase ob) { observers.emplace_back(ob); };nn void Remove(ObserverBase ob) { observers.remove(ob); }nn void Notify() {n for (auto observer : observers) {n observer->Update(); n} n} n n私人: n std :: list觀察者; n}; n nint main(){ n ObserverBase base1 = new ObserverFirstChild(); n ObserverBase * base2 = new ObserverSecondChild(); n n NotifyBase notify; n notify.Add(base2); n notify.Add(base1); n notify.Notify(); n notify.Remove(base1); n notify.Notify(); n n刪除base2; n刪除base1; n返回0; n}“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”通过观察者模式可以灵活的控制依赖的对象,动态的增加和删除需要得到通知的对象。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”装饰器模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”动态的给一个对象添加一些额外的职责,扩展一个类的功能,就增加功能来说,使用装饰器模式比单纯的继承子类更加灵活,不一定非要疯狂使用继承方式。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”举个例子,有游戏这个大类,扩展这个类的功能,有打篮球,踢足球,玩lol,玩卡丁车,可以分别定义继承游戏基类的四个子类,但是如果想组合这几个功能呢,一个对象既会打篮球又会玩卡丁车,既会打篮球又会玩lol,再定义几个类继承游戏基类显然不是好的做法,装饰器模式可以很好的解决这个问题,上代码:”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”首先定义一个Game基类”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef GAMEn#define GAMEnn#include nnclass Game {n public:n Game() {}nn virtual ~Game() {}nn virtual void Skill() { std::cout << "game skill" << std::endl; }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{"type":"text","text":"定义卡丁车子类和lol子类"}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#ifndef _CARGAMEn#define CARGAME_nn#include "game.h"nnclass CarGame : public Game {n public:n void Skill() override { std::cout << "car game" << std::endl; }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#ifndef _LOLGAMEn#define LOLGAME_nn#include "game.h"nnclass LolGame : public Game {n public:n void Skill() override { std::cout << "lol game" Update(); n n刪除impl; n刪除圓圈; n n返回0; n} n輸出: n圓圈形狀更新 n繪製黑色“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”通过桥接模式可以更好的应对变化,应对抽象和实现的多种组合变化。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”工厂模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”工厂模式属于创建型模式,主要用于创建对象时不向外部暴露创建逻辑,通过一个共同的接口指向新创建的对象,通过面向对象的多态,将创建对象的工作延迟到子类执行,由子类决定实例化哪个对象。用于隔离对象使用者与其具体类型之间的耦合关系,当具体类型经常变化时,可以考虑使用工厂模式。有一个类型的抽象基类,同时又有很多继承该抽象基类的具体类型,我们做的就是使其依赖于抽象而不依赖于具体,实现方式是创建一个工厂基类,在为每个具体类型定义一个可以创建其相应对象的工厂,每一个具体类对应一个具体工厂,工厂类继承自工厂基类,通过工厂基类的多态性就可以决定创建什么类型的对象。上代码:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef GAMEn#define GAMEnn#include nnclass Game {n public:n Game() {}n virtual ~Game() {}nn virtual void Play() {n std::cout << "play game" << std::endl;n }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#ifndef BASKETBALLn#define BASKETBALLnn#include "game.h"nnclass BasketBall : public Game {n void Play() override { std::cout << "play basketball" << std::endl; }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:“text”,“text”:“#ifndefSOCKETBALLn#defineSOCKETBALLnn#include”gameh“nnclassSocketBall:公共遊戲{nvoidPlay()優先{{std::cout<<“playsocketball”[{"type":"text""text":"#ifndefSOCKETBALLn#defineSOCKETBALLnn#include"gameh"nnclassSocketBall:publicGame{nvoidPlay()override{std::cout<<"playsocketball"[{“type”:“text”,“text”:“#ifndefSOCKETBALLn#defineSOCKETBALLnn#include”gameh“nnclassSocketBall:公共遊戲{nvoidPlay()優先{{std::cout<<“playsocketball”[{"type":"text""text":"#ifndefSOCKETBALLn#defineSOCKETBALLnn#include"gameh"nnclassSocketBall:publicGame{nvoidPlay()override{std::cout<<"playsocketball"Play(); n n刪除工廠; n刪除遊戲; n n factory = new SocketBallFactory(); n game = factory-> CreateGame(); n game-> Play(); n n刪除工廠; n刪除遊戲; n n返回0; n} n輸出: nplay籃球 nplay壘球“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”当有新类型增加时,需要添加一个具体类和一个相应的创建工厂,尽管减少了耦合度,但是其实还是比较麻烦的。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”抽象工厂方法模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:“text”,“text”:“和工廠方法模式類似,不做過多介紹,說一下定義,抽象工廠方法模式主要提供一個接口,讓該接口負責創建多系列“相關或相互的對象”,無需指定具體的類,系列對象指的是某些特定係列下的對象間有相互依賴或相互作用的關係,不同系列的對象之間不能相互依賴,如果沒有多系列對象創建的需求變化,沒必要使用“},{”type“:”文本“,”標記“:[{“type”:”text””text”:”和工厂方法模式类似,不做过多介绍,说一下定义,抽象工厂方法模式主要提供一个接口,让该接口负责创建多系列“相关或相互的对象”,无需指定具体的类,系列对象指的是某一特定系列下的对象间有相互依赖或相互作用的关系,不同系列的对象之间不能相互依赖,如果没有多系列对象创建的需求变化,没必要使用”}{“type”:”text””marks”:[{“type”:“text”,“text”:“和工廠方法模式類似,不做過多介紹,說一下定義,抽象工廠方法模式主要提供一個接口,讓該接口負責創建多系列“相關或相互的對象”,無需指定具體的類,系列對象指的是某些特定係列下的對象間有相互依賴或相互作用的關係,不同系列的對象之間不能相互依賴,如果沒有多系列對象創建的需求變化,沒必要使用“},{”type“:”文本“,”標記“:[{“type”:”text””text”:”和工厂方法模式类似,不做过多介绍,说一下定义,抽象工厂方法模式主要提供一个接口,让该接口负责创建多系列“相关或相互的对象”,无需指定具体的类,系列对象指的是某一特定系列下的对象间有相互依赖或相互作用的关系,不同系列的对象之间不能相互依赖,如果没有多系列对象创建的需求变化,没必要使用”}{“type”:”text””marks”:[{“type”:”strong”}],“ text”:“抽象工廠方法”},{“ type”:“ text”,“ text”:“模式,使用”},{“ type”:“ text”,“ marks”:[{“type”:”strong”}],“ text”:“簡單工廠方法”},{“ type”:“ text”,“ text”:“模式就可以,拿上一個替換繼續說,遊戲類型是一個系列,我們有了一個遊戲類型的工廠,以後可能會再加入娛樂圈類型的一個系列,那就在做一個娛樂圈類型的系列工廠,以後可能還有文藝類型的系列,那就再加一個文藝類型的系列工廠,隨之就有三個系列的工廠,所以就可以在這三類工廠的基礎上再抽像出一個抽象的超級工廠,根據不同需求選擇實例化哪個一個系列的具體工廠,再創建具體工廠下的具體類型的對象。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”原型模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”用于创建重复的对象,定义一个clone接口,通过调用clone接口创建出与原来类型相同的对象,上代码:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef GAMEn#define GAMEnn#include nnclass Game {n public:n virtual Game* clone() = 0;nn virtual void Play() = 0;n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“”type“:”text“,”text“:”#ifndefBASKETBALLn#defineBASKETBALLnn#include“gameh”nnclassBasketBall:公共遊戲{n虛擬遊戲*clone()覆蓋{n返回新的BasketBall();n}nn虛擬voidPlay()覆蓋{nstd::cout<<“basketball”[{"type":"text""text":"#ifndefBASKETBALLn#defineBASKETBALLnn#include"gameh"nnclassBasketBall:publicGame{nvirtualGame*clone()override{nreturnnewBasketBall();n}nnvirtualvoidPlay()override{nstd::cout<<"basketball"[{“”type“:”text“,”text“:”#ifndefBASKETBALLn#defineBASKETBALLnn#include“gameh”nnclassBasketBall:公共遊戲{n虛擬遊戲*clone()覆蓋{n返回新的BasketBall();n}nn虛擬voidPlay()覆蓋{nstd::cout<<“basketball”[{"type":"text""text":"#ifndefBASKETBALLn#defineBASKETBALLnn#include"gameh"nnclassBasketBall:publicGame{nvirtualGame*clone()override{nreturnnewBasketBall();n}nnvirtualvoidPlay()override{nstd::cout<<"basketball"clone(); n newgame-> Play(); n n刪除遊戲; n刪除new_game; n n返回0; n}“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”单纯看game不知道它是什么类型,它可能是篮球游戏也可能是足球游戏等,如果想创建一个与它相同类型的对象就可以使用原型模式其实就是实现一个clone接口,如果一个对象的拷贝构造函数比较复杂而自己不想使用拷贝构造的方式创建对象也可以使用原型模式,使用方式见上例。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”建造者模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”用于构建一个复杂的大的对象,一个复杂的对象通常需要一步步才可以构建完成,建造者模式强调的是一步步创建对象,并通过相同的构建过程可以获得不同的结果对象,一般来说建造者对象不是直接返回的,与抽象工厂方法区别是抽象工厂方法用于创建多个系列的对象,而建造者模式强调一步步构建对象,并且构建步骤固定,举例:想要构建一个老师类的对象,老师有第一技能和第二技能,第一技能是数学就代表是数学老师,第一技能是英语就代表是语文老师,构造一个老师对象需要先设定老师的第一技能再设定老师的第二技能,强调一步步设定技能,将这一步步的构建过程可以抽象出建造者模式。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”首先定义老师类”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef TEACHERn#define TEACHERnn#include n#include nnclass Teacher {n private:n std::string firstskill;n std::string secondskill;nn public:n void SetFirstSkill(const std::string& skill) { this->firstskill = skill; }nn void SetSecondSkill(const std::string& skill) { this->secondskill = skill; }n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”定义一个老师的抽象构建器,再根据具体老师继承出具体的老师构建器”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef _TEACHERABSTRACTBUILDERn#define TEACHERABSTRACTBUILDER_nn#include “teacher.h”nnclass TeacherAbstractBuilder {n public:n TeacherAbstractBuilder() {}n virtual ~TeacherAbstractBuilder() {}nn virtual void BuildFirstSkill() = 0;n virtual void BuildSecondSkill() = 0;nn virtual Teacher* GetTeacher() = 0;n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef _MATHTEACHERBUILDERn#define MATHTEACHERBUILDERnn#include “teacherabstractbuilder.h”nnclass MathTeacherBuilder : public TeacherAbstractBuilder {n public:n MathTeacherBuilder() { this->teacher = new Teacher(); }nn ~MathTeacherBuilder() { delete this->teacher; }nn Teacher GetTeacher() { return this->teacher; }nn void BuildFirstSkill() { this->teacher->SetFirstSkill(“math”); }nn void BuildSecondSkill() { this->teacher->SetSecondSkill(“english”); }nn private:n Teacher teacher_;n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef _ENGLISHTEACHERBUILDERn#define ENGLISHTEACHERBUILDERnn#include “teacherabstractbuilder.h”nnclass EnglishTeacherBuilder : public TeacherAbstractBuilder {n public:n EnglishTeacherBuilder() { this->teacher = new Teacher(); }nn ~EnglishTeacherBuilder() { delete this->teacher; }nn Teacher GetTeacher() { return this->teacher; }nn void BuildFirstSkill() { this->teacher->SetFirstSkill(“english”); }nn void BuildSecondSkill() { this->teacher->SetSecondSkill(“math”); }nn private:n Teacher teacher_;n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”定义一个稳定的Director类,由它根据具体的老师构建器决定构建哪一个老师”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef DIRECTORn#define DIRECTORnn#include “teacherabstractbuilder.h”nnclass Director {n public:n Director(TeacherAbstractBuilder builder) { this->builder = builder; }nn ~Director() {}nn void Create() {n this->builder->BuildFirstSkill();n this->builder->BuildSecondSkill();n }nn private:n TeacherAbstractBuilder builder;n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”使用方法如下:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#include “director.h”n#include “englishteacherbuilder.h”n#include “mathteacherbuilder.h”nnint main() {n TeacherAbstractBuilder builder = new MathTeacherBuilder();n Director director = new Director(builder);n delete builder;n delete director;nn builder = new EnglishTeacherBuilder();n director = new Director(builder);n delete builder;n delete director;nn return 0;n}”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”通过Director利用不同的具体构建器都采用相同的步骤一步步构建出不同的具体的老师类对象。”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”单例模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”不多说了,网上太多了,列一段单例的代码:”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”static SingleTon& GetInstance() {n static SingleTon t;n return t;n }”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{“type”:”text”,”text”:”享元模式”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”通过共享技术有效支持大量细粒度的对象,主要解决面向对象代价问题,通过共享有效降低创建的对象个数,类似于对象池。 “}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{“type”:”text”,”text”:”举例:篮球分多种颜色,我想要蓝色的篮球想要红色的篮球这就需要创建两个对象,当我再想要一个蓝色的篮球如果能够继续使用之前的那个对象就更好,通过享元模式可以做到。”}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef BASKETBALLn#define BASKETBALLnn#include n#include nnclass BasketBall {n public:n BasketBall(const std::string& color) : color(color) {}n ~BasketBall() {}nn private:n std::string color;n};nn#endif”}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#ifndef _BASKETBALLFACTORYn#define BASKETBALLFACTORYnn#include n#include “basketball.h”nnclass BasketballFactory {n private:n std::unorderedmap map;nn public:n BasketBall GetBasketBallWithColor(const std::string& color) {n if (map.find(color) == map.end()) {n BasketBall* p = new BasketBall(color);n map[color] = p; n return p; n} else { n返回地圖[color]; n} n} n}; n n#endif“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{“type”:”text”,”text”:”#include “BasketballFactory.h”nnint main() {n BasketballFactory factory;n BasketBall whiteball1 = factory.GetBasketBallWithColor(“white”);n BasketBall blackball1 = factory.GetBasketBallWithColor(“black”);n BasketBall whiteball2 = factory.GetBasketBallWithColor(“white”);n BasketBall blackball2 = factory.GetBasketBallWithColor(“black”);n std::cout << whiteball1 << std::endl;n std::cout << whiteball2 << std::endl;n std::cout << blackball1 << std::endl;n std::cout << blackball2 << std::endl;n // remember to deleten return 0;n}n输出:n0x7fffe4984e70n0x7fffe4984e70n0x7fffe4984f00n0x7fffe4984f00"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{"type":"text","text":"外观模式(Facade Pattern)"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{"type":"text","text":"感觉外观模式没啥特别的,感觉就是做好功能之间边界的划分,做好封装,弄清楚哪部分是稳定的,哪部分是变化的,对外稳定松耦合,对内迭代变化高内聚,子系统的内部外部要做好解耦,为子系统的一组接口提供一个稳定一致的(界面),子系统中的任何变化都不会影响这个(界面)的变化。"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ heading” ,“ attrs”:{“ align”:null,“ level”:3},“ content”:[{"type":"text","text":"代理模式(Proxy Pattern)"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null},“ content”:[{"type":"text","text":"为其它对象提供一种代理以控制这个对象的访问,一般对于比较大的对象访问比较困难或者或带来很多麻烦,例如裸指针的使用,所以一般使用智能指针来控制裸指针,使用智能指针也是一种代理模式,举例:A喜欢B想送给B礼物,但是却不认识B,而C却认识B,所以可以把C作为A的代理去送给B礼物,代码:"}]},{“ type”:“ codeblock”,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#ifndef GIRLn#define GIRLnn#include n#include nnclass Girl {n private:n std::string name;nn public:n Girl(const std::string &name) : name(name) {}nn std::string GetName() const noexcept { return name_; }n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{"type":"text","text":"#ifndef GIFTn#define GIFTnn#include "girl.h"nnclass Gift {n public:n virtual void GiveGift() = 0;n};nn#endif"}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ codeblock” ,“ attrs”:{“ lang”:“ cpp”},“ content”:[{{“type”:“text”,“text”:“#ifndef_GIFTPROXYn#defineGIFTPROXYnn#include”gifth“n#include”girlh“nnclassGiftProxy:公共禮物{npublic:nGiftProxy(Girlgirl):girl(girl){}nnvoidGiveGift()overlay{std::cout<<“send”<<<處理(this); n} n} n void ChangeState(State * pState){state_ = pState; } n私人: n狀態* state _; n}; n nclass ConcreteStateA:公共狀態{ n公共: n void Handle(Context * context)覆蓋{cout << “我是狀態a ” << endl; } n}; n nclass ConcreteStateB:公共狀態{ n public: n void Handle(Context * context)覆蓋{cout << “我是國家b ” ChangeState(state_b); n context-> Request(); n n刪除上下文; n刪除state_b; n刪除state_a; n n返回0; n}“}]},{“ type”:“ paragraph”,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}},{“ type”:“ paragraph” ,“ attrs”:{“ indent”:0,“ number”:0,“ align”:null,“ origin”:null}}]}