设计模式解决的问题
少量代码适应需求改变
运行时多态(虚函数重写)
静态多态(方法重载)
原则
单一指责
接口隔离(public,privte)
开闭原则(对扩展开放,对修改关闭)
最小知道原则
里氏替换原则
模板模式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> using namespace std; // 开闭 class ZooShow { public: void Show() { // 如果子表演流程没有超时的话,进行一个中场游戏环节;如果超时,直接进入下一个子表演流程 if (Show0()) PlayGame(); Show1(); Show2(); Show3(); } private: void PlayGame() { cout << "after Show0, then play game" << endl; } bool expired; // 对其他用户关闭,但是子类开放的 protected: virtual bool Show0() { cout << "show0" << endl; if (! expired) { return true; } return false; } virtual void Show2() { cout << "show2" << endl; } virtual void Show1() { } virtual void Show3() { } }; // 框架 // 模板方法模式 class ZooShowEx10 : public ZooShow { protected: virtual void Show0() { if (! expired) { return true; } return false; } } class ZooShowEx1 : public ZooShow { protected: virtual bool Show0() { cout << "ZooShowEx1 show0" << endl; if (! expired) { // 里氏替换 return true; } return false; } virtual void Show2(){ cout << "show3" << endl; } }; class ZooShowEx2 : public ZooShow { protected: virtual void Show1(){ cout << "show1" << endl; } virtual void Show2(){ cout << "show3" << endl; } }; class ZooShowEx3 : public ZooShow { protected: virtual void Show1(){ cout << "show1" << endl; } virtual void Show3(){ cout << "show3" << endl; } virtual void Show4() { // } }; /* */ int main () { ZooShow *zs = new ZooShowEx10; // 晚绑定还是早绑定 // ZooShow *zs1 = new ZooShowEx1; // ZooShow *zs2 = new ZooShowEx2; zs->Show(); return 0; }
责任链模式
有一个请求处理流程,处理流程可以通过链表进行链接起来,请求会沿着链表传递,如果当前流程能够处理完成就返回值
nginx
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <memory> #include <string> class Context { public: std::string name; int day; }; // 稳定点 抽象 变化点 扩展 (多态) // 从单个处理节点出发,我能处理,我处理,我不能处理交给下一个人处理 // 链表关系如何抽象 class HandleByMainProgram; class HandleByProjMgr; class HandleByBoss; class HandleByBeauty; class IHandler { public: IHandler() : next(nullptr) {} virtual ~IHandler(); void SetNextHandler(IHandler *next) { // 链表关系 next = next; } bool Handle(const Context &ctx) { if (CanHandle(ctx)) { return HandleRequest(ctx); } else if (GetNextHandler()) { return GetNextHandler()->Handle(ctx); } else { // err } return false; } static IHandler* make_handler_list() { IHandler * h0 = new HandleByBeauty(); IHandler * h1 = new HandleByMainProgram(); IHandler * h2 = new HandleByProjMgr(); IHandler * h3 = new HandleByBoss(); h0->SetNextHandler(h1); h1->SetNextHandler(h2); h2->SetNextHandler(h3); return h0; } protected: virtual bool HandleRequest(const Context &ctx) = 0; virtual bool CanHandle(const Context &ctx) = 0; IHandler * GetNextHandler() { return next; } private: IHandler *next; // 组合基类指针 }; class Request { public: Request() { handler = IHandler::make_handler_list(); } bool Handle(const Context &ctx) { return handler->Handle(ctx); } private: IHandler *handler; }; class HandleByMainProgram : public IHandler { protected: virtual bool HandleRequest(const Context &ctx){ // return true; } virtual bool CanHandle(const Context &ctx) { // if (ctx.day <= 1) return true; return false; } }; class HandleByProjMgr : public IHandler { protected: virtual bool HandleRequest(const Context &ctx){ // return true; } virtual bool CanHandle(const Context &ctx) { // if (ctx.day <= 20) return true; return false; } }; class HandleByBoss : public IHandler { protected: virtual bool HandleRequest(const Context &ctx){ // return true; } virtual bool CanHandle(const Context &ctx) { // if (ctx.day < 30) return true; return false; } }; class HandleByBeauty : public IHandler { protected: virtual bool HandleRequest(const Context &ctx){ // return true; } virtual bool CanHandle(const Context &ctx) { // if (ctx.day <= 3) return true; return false; } }; int main() { // IHandler * h1 = new HandleByMainProgram(); // IHandler * h2 = new HandleByProjMgr(); // IHandler * h3 = new HandleByBoss(); // h1->SetNextHandler(h2); // h2->SetNextHandler(h3); // 抽象工厂 // nginx http 处理 // 设置下一指针 Context ctx; auto req = std::make_unique<Request>(); req->Handle(ctx); return 0; }
组合模式(工厂模式)
抽象公共的方法,服装——》男装,女装-》西服。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class IComponent { public: IComponent(/* args */); ~IComponent(); virtual void Execute() = 0; virtual void AddChild(IComponent *ele) {} virtual void RemoveChild(IComponent *ele) {} }; class Leaf : public IComponent{ public: virtual void Execute() { cout << "leaf exxcute" << endl; } }; class Composite : public IComponent { private: std::list<IComponent*> _list; public: virtual void AddChild(IComponent *ele) { // ... } virtual void RemoveChild(IComponent *ele) { // ... } virtual void Execute() { for (auto iter = _list.begin(); iter != _list.end(); iter++) { iter->Execute(); } } };
策略模式
商城节假日有促销活动,加大促销力度,现在提示国庆节的活动规格
日志的容错机制
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Context { }; // 稳定点:抽象去解决它 // 变化点:扩展(继承和组合)去解决它 class ProStategy { public: virtual double CalcPro(const Context &ctx) = 0; virtual ~ProStategy(); }; // cpp class VAC_Spring : public ProStategy { public: virtual double CalcPro(const Context &ctx){ } }; class VAC_Spring_v2 : public VAC_Spring { public: virtual double CalcPro(const Context &ctx){ //.... } }; class VAC_worker : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; // cpp class VAC_QiXi : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; class VAC_QiXi1 : public VAC_QiXi { public: virtual double CalcPro(const Context &ctx){} }; // cpp class VAC_Wuyi : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; // cpp class VAC_GuoQing : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; class VAC_GuoQing2 : public VAC_GuoQing { public: virtual double CalcPro(const Context &ctx){} }; class VAC_Shengdan : public ProStategy { public: virtual double CalcPro(const Context &ctx){} }; // 设计原则:接口隔离原则 // 组合、继承 // 组合基类指针 // 两种方法:1. 采用具体接口选择算法 2. 依赖注入 class Promotion { public: Promotion(ProStategy *sss = nullptr) : s(sss){} ~Promotion(){} void Choose(ProStategy *sss) { // 条件选择 if (sss != nullptr) { s = sss; } } double CalcPromotion(const Context &ctx){ if (s != nullptr) { return s->CalcPro(ctx); } return 0.0L; } private: ProStategy *s; }; int main () { Context ctx; ProStategy *s = new VAC_QiXi1(); Promotion *p = new Promotion(s); p->Choose(new VAC_GuoQing2()); p->CalcPromotion(ctx); return 0; }
观察者模式
当一个对象发生改变的时候,如何让他依赖的多个对象自动更新
up主跟新视频通知其他关注他的人
根据等级开放不同的权限
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <list> #include <algorithm> using namespace std; // class IDisplay { public: virtual void Show(float temperature) = 0; virtual ~IDisplay() {} }; class DisplayA : public IDisplay { public: virtual void Show(float temperature) { cout << "DisplayA Show" << endl; } private: void jianyi(); }; class DisplayB : public IDisplay{ public: virtual void Show(float temperature) { cout << "DisplayB Show" << endl; } }; class DisplayC : public IDisplay{ public: virtual void Show(float temperature) { cout << "DisplayC Show" << endl; } }; class DisplayD : public IDisplay{ public: virtual void Show(float temperature) { cout << "DisplayC Show" << endl; } }; class WeatherData { }; // 应对稳定点,抽象 // 应对变化点,扩展(继承和组合) class DataCenter { public: void Attach(IDisplay * ob) { // } void Detach(IDisplay * ob) { // } void Notify() { float temper = CalcTemperature(); for (auto &ob : obs) { ob->Show(temper); } } // 接口隔离 private: WeatherData * GetWeatherData(); float CalcTemperature() { WeatherData * data = GetWeatherData(); // ... float temper/* = */; return temper; } std::list<IDisplay*> obs; }; int main() { // 单例模式 DataCenter *center = new DataCenter; // ... 某个模块 IDisplay *da = new DisplayA(); center->Attach(da); // ... IDisplay *db = new DisplayB(); center->Attach(db); IDisplay *dc = new DisplayC(); center->Attach(dc); center->Notify(); //----- center->Detach(db); center->Notify(); center->Notify(); return 0; }