第五天:模板方法-外观模式-观察者模式
模板方法: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.
当我们要完成在某一细节层次一致的一个过程或一些列步骤,但其个别步骤在更详细的层次上的实现可能不同时,通常考虑用模板方法来处理.
算法步骤固定,但其中某个或某些步骤会发生变化时,将变化的步骤抽象, 由子类去实现.而策略模式是客户端对不受(或较少受到)算法间的切换的影响.针对的是不同的算法.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.
1.在设计初期阶段,应该要有意识的将不同的两个层分离.层与层之间建立外观
2.在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,这时增加外观Facade可以提供一个简单的接口,减少他们之间的依赖.
3.在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,此时使用Facade模式,为新系统开发一个外观类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 namespace Subsystem 2 { 3 class A 4 { 5 public: 6 void Fun(){} 7 }; 8 9 class B 10 { 11 public: 12 void Fun1(){} 13 void Fun2(){} 14 }; 15 16 class C 17 { 18 public: 19 void Fun(){} 20 }; 21 }; 22 23 namesapce NewSystem 24 { 25 class Facade 26 { 27 public: 28 void Func1() 29 { 30 a_.Fun(); 31 b_.Fun1(); 32 } 33 34 void Func2() 35 { 36 b_.Fun2(); 37 c_.Fun(); 38 } 39 private: 40 Subsystem::A a_; 41 Subsystem::B b_; 42 Subsystem::C c_; 43 }; 44 45 //client 46 { 47 Facade face; 48 face.Func1(); 49 face.Func2(); 50 } 51 //此时将新系统和(旧)子系统就隔离开,在新系统中使用Facade提供的接口 52 //而实现细节却是由子系统定义的.如果需要更换子系统也只需要修改Facade, 53 //而不需要或较少量修改新系统 54 }
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时会通知所有观察者对象,使它们能够自动更新自己.
何时? 当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变.+
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 class Subscriber 2 { 3 public: 4 virtual void NotifyToReadNews() = 0; 5 }; 6 7 class Blog 8 { 9 public: 10 virtual void Subscribe(Subscriber*); 11 virtual void Publish() = 0; 12 virtual void UnSubscribe(Subscriber*); 13 14 protected: 15 vector<Subscriber*> subscribers_; 16 }; 17 18 19 class CelebrityBlog : public Blog 20 { 21 public: 22 void Publish() 23 { 24 for(auto it = subscribers_.begin(); it!=subscribers_.end(); ++it) 25 { 26 (*it)->NotifyToReadNews(); 27 } 28 } 29 }; 30 31 32 class MyReader : public Subscriber 33 { 34 public: 35 void NotifyToReadNews() 36 { 37 //do something 38 } 39 }; 40 41 //client system 42 int sys() 43 { 44 CelebrityBlog blog; 45 MyReader my; 46 blog.Subscribe(&my); 47 //my的NotifyToReadNews()会被调用 48 }