- \n#include \"observerfirstchild.h\"\n#include \"observersecondchild.h\"\n\nclass NotifyBase {\n public:\n void Add(ObserverBase ob) { observers.emplace_back(ob); };\n\n void Remove(ObserverBase ob) { observers.remove(ob); }\n\n void Notify() {\n for (auto observer : observers) {\n observer->Update();\n }\n }\n\n private:\n std::list
一文学会设计模式
{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最近在研究设计模式,发现尽管设计模式是针对面向对象语言提出的,但貌似市面上大多数都是基于java给出的例子,C++的例子极少,自己看完李建忠老师的GOF设计模式视频后查阅各种资料并结合自身实践总结如下,希望对大家有所帮助。"}]},{"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}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"面向对象特点"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"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 GAME\n#define GAME\n\n#include \n\nclass Game {\n public:\n Game() {}\n\n virtual ~Game() {}\n\n void Run() {\n InitGame();\n StartGame();\n StopGame();\n }\n\n protected:\n virtual void StartGame() { std::cout << \"step 2: start game\" << std::endl; }\n\n private:\n void InitGame() { std::cout << \"step 1: init game\" << std::endl; }\n void StopGame() { std::cout << \"step 3: stop game\" << std::endl; }\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 \"game.h\"\n\nclass 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 \"game.h\"\n\nclass SocketBall : public Game {\n void StartGame() override { std::cout << \"start socketball 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 \"basketball.h\"\n#include \"socketball.h\"\n\nint main() {\n Game game = new BasketBall();\n game->Run();\n delete game;\n Game game2 = new SocketBall();\n game2->Run();\n delete game2;\n return 0;\n}\ng++ test.cc -std=c++11 && ./a.out\n输出:\nstep 1: init game\nstart basketball game\nstep 3: stop game\nstep 1: init game\nstart socketball game\nstep 3: stop game"}]},{"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 sub\n};\n\nint 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-else\n 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 CALCULATION\n#define CALCULATION\n\n#include \n\nclass Calculation {\n public:\n Calculation() {}\n\n virtual ~Calculation() {}\n\n virtual void operation() { std::cout << \"base operation\" << std::endl; }\n};\n\n#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 ADD\n#define ADD\n\n#include \"calculation.h\"\n\nclass Add : public Calculation {\n void operation() override { std::cout << \"this is add operation\" << std::endl; }\n};\n\n#endif"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"#ifndef SUB\n#define SUB\n\n#include \"calculation.h\"\n\nclass Sub : public Calculation {\n void operation() override { std::cout << \"this is sub operation\" << std::endl; }\n};\n\n#endif"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"int Stragegy() {\n Calculation cal = new Add();\n cal->operation();\n delete cal;\n\n Calculation cal2 = new Sub(); // 这里将来都可以用工厂模式改掉,不会违反开放封闭原则\n cal2->operation();\n delete cal2;\n\n return 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 OBSERVER\n#define OBSERVER\n\n#include \n\nclass ObserverBase {\n public:\n ObserverBase() {}\n virtual ~ObserverBase() {}\n\n virtual void Update() {}\n};\n\n#endif"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"cpp"},"content":[{"type":"text","text":"#ifndef _OBSERVERFIRSTCHILD\n#define OBSERVERFIRSTCHILD_\n\n#include \"observer.h\"\n\nclass ObserverFirstChild : public ObserverBase {\n void Update() override {\n std::cout << \"first child receive notify\" << std::endl;\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":"#ifndef _OBSERVERSECONDCHILD\n#define OBSERVERSECONDCHILD_\n\n#include \"observer.h\"\n\nclass ObserverSecondChild : public ObserverBase {\n void Update() override {\n std::cout << \"second child receive notify\" << std::endl;\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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.