设计模式
- 模板模式 Template Method
定义一个算法的骨架(稳定不变),而将算法中的一些步骤延迟(变化)到子类中,template method可以使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
#include <iostream> // 网购类 class OnlineShopping { public: virtual void selectProduct() = 0; //可变化的 virtual void addToCart() = 0; //可变化的 virtual void account() = 0; //可变化的 void Login(){} //稳定的 //稳定不变的算法流程 void shopping() { Login(); selectProduct(); addToCart(); account(); } virtual ~OnlineShopping() //虚析构函数 { std::cout << "网购类析构" << std::endl; } }; // 淘宝类子类-子类重写网购类的算法的某些步骤 class TaoBao : public OnlineShopping { virtual void selectProduct() { std::cout << "在淘宝选商品" << std::endl; } virtual void addToCart() { std::cout << "将商品加入淘宝购物车" << std::endl; } virtual void account() { std::cout << "清空淘宝购物车" << std::endl; } virtual ~TaoBao() { std::cout << "淘宝类析构" << std::endl; } }; int main() { //父类指针指向子类对象,调用虚函数时执行动态绑定 OnlineShopping *shop = new TaoBao(); shop->shopping(); delete shop; return 0; } |
- 策略模式 strategy method
定义一系列算法,把他们一个个封装起来,并且使他们可互相替换(变化),该模式使得算法独立于使用它的客户程序(稳定)而变化(扩展)
#include <iostream> using namespace std; //策略类 class TaxStrategy { public: virtual void Calculate(const int& c) = 0; //变化的 virtual ~TaxStrategy(){cout<<"析构策略类"<<endl;} }; //中国税法子类 class CNTax:public TaxStrategy { public: virtual void Calculate(const int& c) { cout<<"中国税法类的计算"<<endl; } virtual ~CNTax(){cout<<"析构中国税法类"<<endl;} }; //美国税法子类 class USTax:public TaxStrategy //新增扩展 { public: virtual void Calculate(const int& c) { cout<<"美国税法类的计算"<<endl; } virtual ~USTax(){cout<<"析构美国税法类"<<endl;} }; //稳定算法流程程序类 class SalesOrder { public: SalesOrder(TaxStrategy* strate){this->strategy = strate;} void CalculateTax() { strategy->Calculate(0); //多态调用 } ~SalesOrder(){delete this->strategy;} private: TaxStrategy* strategy; }; int main() { SalesOrder s(new USTax()); s.CalculateTax(); } |
- 观察者模式
定义对象间的一种一对多的依赖关系(变化),当一个对象状态发生变化时,所有依赖他的对象都得到通知并自动更新
#include <iostream> #include <string> #include <list> using namespace std; //观察者基类-人(稳定) class Person { public: string state; //状态 string name; //姓名 Person(string name_) : state("空闲"), name(name_) {} virtual void updateState(string s) = 0; //不同的人的收到信号改变成各自的状态,是可变化的 virtual ~Person() {} }; //具体观察者-学生 class Student : public Person //学生老师这些角色的添加不应该影响学校类 { public: Student(string name) : Person(name) {} void updateState(string s) { state = s; } //学生遵从收到的信号 }; //具体观察者-老师 class Teacher : public Person { public: Teacher(string name) : Person(name) {} void updateState(string s) { state = "监督学生" + s; } //老师监督学生遵从收到的信号 }; //学校-具体被观察对象(稳定) class School { public: void register_person(Person *p) { this->AllStudents.push_back(p); } //学校的通知是稳定不变的 void Notify(string state) { for (auto temp = this->AllStudents.begin(); temp != AllStudents.end(); ++temp) { string preState = (*temp)->state; (*temp)->updateState(state); cout << (*temp)->name << ":" << preState << "->" << (*temp)->state << endl; } } virtual ~School() { while (!AllStudents.empty()) { Person *temp = AllStudents.front(); AllStudents.pop_front(); delete temp; } } private: list<Person *> AllStudents; }; int main() { School u; Person *p = new Student("张三"); u.register_person(p); p->updateState("学习"); Person *p1 = new Teacher("李老师"); u.Notify("睡觉"); u.register_person(p1); p1->updateState("吃饭"); //多态调用,根据对象类型动态绑定 u.register_person(new Student("王五")); u.Notify("读书"); return 0; } |
- 装饰模式 decorator
动态(组合)的给一个对象增加额外的职责,就增加功能而言,decorator比生成子类(继承)更为灵活(消除重复代码和减少子类个数)
#include <iostream> #include <string> using namespace std; //稳定不变的 class Stream { public: virtual void Read(int number) = 0; virtual void Write(int number) = 0; virtual ~Stream() {} }; class FileStream : public Stream //新增流类型-变化 { public: virtual void Read(int number) { cout << "FileStream读流!" << endl; } virtual void Write(int number) { cout << "FileStream写流!" << endl; } }; class NetworkStream : public Stream //新增流类型-变化 { public: virtual void Read(int number) { cout << "NetworkStream读流!" << endl; } virtual void Write(int number) { cout << "NetworkStream写流!" << endl; } }; class Decorator : public Stream //装饰器-稳定不变的 { public: Decorator(Stream *s) : stream(s) {} protected: Stream *stream; }; class StreamBuffer : public Decorator //新增装饰/操作类型-变化 { public: StreamBuffer(Stream *s) : Decorator(s) {} virtual void Read(int number) { cout << "已先buffer操作!" << endl; stream->Read(number); } virtual void Write(int number) { stream->Write(number); cout << "已后buffer操作!" << endl; } }; class StreamCrypto : public Decorator //新增装饰/操作类型-变化 { public: StreamCrypto(Stream *s) : Decorator(s) {} virtual void Read(int number) { stream->Read(number); cout << "已解密操作!" << endl; } virtual void Write(int number) { cout << "已加密操作!" << endl; stream->Write(number); } }; int main() { Stream *s1 = new FileStream(); //原文件流 s1->Read(0); s1->Write(0); cout<<"-"<<endl; Stream *s2 = new StreamCrypto(s1); //直接加密 s2->Read(0); s2->Write(0); cout<<"--"<<endl; Stream *s3 = new StreamBuffer(s1); //直接缓冲 s3->Read(0); s3->Write(0); cout<<"---"<<endl; Stream *s4 = new StreamBuffer(s2); //对加密的缓冲 s4->Read(0); s4->Write(0); delete s4,s3,s2,s1; return 0; } |
- 桥模式 brige
将抽象部分(业务功能)与实现部分(平台实现)分离,使他们都可以独立的变化
#include <iostream> #include <string> using namespace std; class MessagerImp //稳定不变的 { public: virtual void PlaySound() = 0; virtual void DrawShape() = 0; virtual ~MessagerImp() {} }; class Messager //稳定不变的 { public: Messager(MessagerImp *mImp) : messageImp(mImp) {} virtual void Login(string username, string password) = 0; virtual void SendMessage(string message) = 0; virtual void SendPicture() = 0; virtual ~Messager() {} protected: MessagerImp *messageImp; }; class PCMessagerImp : public MessagerImp //PC端还是移动端是可变的 { public: virtual void PlaySound() { cout << "PC端播放声音!" << endl; } virtual void DrawShape() { cout << "PC端画图形!" << endl; } }; class MobileMessagerImp : public MessagerImp //PC端还是移动端是可变的 { public: virtual void PlaySound() { cout << "Mobile端播放声音!" << endl; } virtual void DrawShape() { cout << "Mobile端画图形!" << endl; } }; class MessagerLite : public Messager //专业版还是轻便版是可变的 { public: MessagerLite(MessagerImp *m) : Messager(m) {} virtual void Login(string username, string password) { cout << "Lite端 用户" << username << "已登录" << endl; } virtual void SendMessage(string message) { cout << "Lite端 用户发消息:" << message << endl; } virtual void SendPicture() { cout << "Lite端 用户发图片" << endl; } }; class MessagerPro : public Messager //专业版还是轻便版是可变的 { public: MessagerPro(MessagerImp *m) : Messager(m) {} virtual void Login(string username, string password) { cout << "Pro端 用户" << username << "已登录" << endl; } virtual void SendMessage(string message) { cout << "Pro端 用户发消息:" << message << endl; messageImp->PlaySound(); } virtual void SendPicture() { cout << "Pro端 用户发图片" << endl; messageImp->DrawShape(); } }; int main() { MessagerImp *mImp1 = new PCMessagerImp(); MessagerImp *mImp2 = new MobileMessagerImp(); Messager *m1 = new MessagerLite(mImp1); //PC轻便版 Messager *m2 = new MessagerPro(mImp1); //PC专业版 Messager *m3 = new MessagerLite(mImp2); //Mobile轻便版 Messager *m4 = new MessagerPro(mImp2); //Mobile专业版 m1->Login("张三", ""); m1->SendMessage(""); m2->Login("李四", ""); m2->SendPicture(); m3->Login("王五", ""); m4->SendPicture(); delete m4, m3, m2, m1, mImp2, mImp1; return 0; } |
- 工厂方法模式 factory method
定义一个用于创建对象的接口(稳定),让子类决定(变化)去实例化哪一个类,factory method使得一个类的实例化延迟到子类
#include <iostream> using namespace std; class Product //产品基类-稳定 { public: virtual void Show() = 0; }; class ProductA : public Product //具体产品,多变的 { public: void Show(){cout << "I'm ProductA" << endl;} }; class ProductB : public Product //具体产品,多变的 { public: void Show(){cout << "I'm ProductB" << endl;} }; class Factory //工厂基类-稳定 { public: virtual Product *CreateProduct() = 0; }; class FactoryA : public Factory //生产对应产品的工厂(new),多变的 { public: Product *CreateProduct() { return new ProductA(); } }; class FactoryB : public Factory //生产对应产品的工厂(new),多变的 { public: Product *CreateProduct(){return new ProductB();} }; void Process(Factory* fact) //主调用函数,全是调用抽象方法,稳定 { Factory *factoryA = fact; Product *productA = factoryA->CreateProduct(); //多态调用new productA->Show(); delete factoryA; delete productA; } int main() { Process(new FactoryA); Process(new FactoryB); return 0; } |
- 抽象工厂模式 abstract factory
提供一个接口(稳定),让该接口创建一系列相关或相互依赖的对象(变化),无需指定具体的类
#include <iostream> using namespace std; class KeyBoard //键盘基类-稳定 { public: virtual void show() = 0; }; class KeyBoardMicro : public KeyBoard //具体键盘类-变化 { public: void show() { cout << "微软的键盘" << endl; } }; class KeyBoardLenovo : public KeyBoard //具体键盘类-变化 { public: void show() { cout << "联想的键盘" << endl; } }; class Drive //驱动抽象基类-稳定 { public: virtual void show() = 0; }; class DriveMicro : public Drive //具体驱动类-变化 { public: void show() { cout << "微软的驱动" << endl; } }; class DriveLenovo : public Drive //具体驱动类-变化 { public: void show() { cout << "联想的驱动" << endl; } }; class Factory //工厂抽象基类-稳定 { public: virtual KeyBoard *createKeyBoard() = 0; virtual Drive *createDrive() = 0; }; class FactoryMicro : public Factory // 微软的工厂-变化 { public: KeyBoard *createKeyBoard() { return new KeyBoardMicro(); } Drive *createDrive() { return new DriveMicro(); } }; class FactoryLenovo : public Factory // 联想的工厂-变化 { public: KeyBoard *createKeyBoard() { return new KeyBoardLenovo(); } Drive *createDrive() { return new DriveLenovo(); } }; int main() { Factory *p = new FactoryMicro(); //提供接口传入抽象类指针 KeyBoard *pK = p->createKeyBoard(); //多态调用new-稳定 Drive *pD = p->createDrive(); //多态调用new-稳定 pK->show(); //稳定 pD->show(); //稳定 delete pD, pK, p; return 0; } |
- 原型模式 prototype method
这种模式是实现了一个原型接口(稳定),该接口用于创建当前对象(变化)的克隆。当直接创建对象的代价比较大时,则采用这种模式。
#include <iostream> #include <string> using namespace std; class Prototype //原型类-稳定 { public: Prototype() {} virtual ~Prototype() {} virtual Prototype *Clone() = 0; virtual void setWorkExperience(string timeArea, string company) {} virtual void setPersonalInfo(string sex, string age) {} virtual void display() {} }; class WorkExperiment : public Prototype //工作经历-变化 { public: WorkExperiment() {} ~WorkExperiment() {} WorkExperiment(const WorkExperiment &wo) : workDate(wo.workDate), company(wo.company) {} WorkExperiment *Clone() override { return new WorkExperiment(*this); } string workDate; string company; }; class Resume : public Prototype //简历-变化 { public: Resume() {} ~Resume() { delete work; } Resume(string name) : name(name) { work = new WorkExperiment(); } void setPersonalInfo(string sex, string age) override { this->sex = sex; this->age = age; } void setWorkExperience(string workDate, string company) override { work->workDate = workDate; work->company = company; } void display() override { cout << name << " " << sex << " " << age << " " << work->workDate << " " << work->company << endl; } Prototype *Clone() override { Resume *obj = new Resume(this->work); //深拷贝实现 obj->name = this->name; //调用私有的构造方法,让工作经历克隆完成, obj->sex = this->sex; //然后再给这个简历对象的相关字段赋值,最终返回一个深复制的简历对象 obj->age = this->age; return obj; } private: Resume(WorkExperiment *work) { this->work = work->Clone(); } string name; string sex; string age; string timeArea; string company; WorkExperiment *work; }; int main() { Prototype *p1 = new Resume("小刘"); p1->setPersonalInfo("男", "25"); p1->setWorkExperience("1998-2000", "xx公司"); Prototype *p2 = p1->Clone(); p2->setWorkExperience("2000-2006", "YY企业"); Prototype *p3 = p1->Clone(); p3->setPersonalInfo("男", "28"); p1->display(); p2->display(); p3->display(); delete p1, p2, p3; return 0; } |
- 建造者模式 builder pattern
将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)
#include <iostream> using namespace std; class House //房屋类(当前未写房屋类的继承) { public: string floor; string wall; string roof; }; class Builder //建造类基类-稳定 { public: Builder() { pHouse = new House; } virtual ~Builder() { delete pHouse; } House *GetResult() { return pHouse; } virtual void BuildFloor() = 0; virtual void BuildWall() = 0; virtual void BuildWindow() = 0; virtual void BuildRoof() = 0; protected: House *pHouse; }; class StoneHouseBuilder : public Builder //石房子-变化 { public: virtual void BuildFloor(){cout << "石房子建地板!" << endl;pHouse->floor = "石头地板";} virtual void BuildWall(){cout << "石房子建墙壁!" << endl;pHouse->wall = "石头墙";} virtual void BuildWindow() { cout << "石房子开窗口!" << endl; } virtual void BuildRoof(){cout << "石房子搭房顶!" << endl;pHouse->roof = "石头屋顶";} }; class TreeHouseBuilder : public Builder //木房子-变化 { public: virtual void BuildFloor(){cout << "木房子建地板!" << endl;pHouse->floor = "木头地板";} virtual void BuildWall(){cout << "木房子建墙壁!" << endl;pHouse->wall = "木头墙";} virtual void BuildWindow() { cout << "木房子开窗口!" << endl; } virtual void BuildRoof(){cout << "木房子搭房顶!" << endl;pHouse->roof = "木头屋顶";} }; class Director //构造的指挥官-稳定 { public: Director(Builder *builder) { m_pBuilder = builder; } House *Create() { m_pBuilder->BuildFloor(); for (int i = 0; i < 4; i++) { m_pBuilder->BuildWall(); } m_pBuilder->BuildWindow(); m_pBuilder->BuildRoof(); return m_pBuilder->GetResult(); } private: Builder *m_pBuilder; }; int main() { Builder *b = new TreeHouseBuilder(); Director *d = new Director(b); House *h = d->Create(); delete d, b; return 0; } |
- 单例模式 singleton
保证一个类仅有一个实例,并提供该实例的全局访问点
class Singleton //饿汉式方法-线程安全(因为在进入main函数之前就已经实例化了类的对象) { public: static Singleton* GetInstance() { return instance1; } private: Singleton(){ }; ~Singleton(){}; Singleton(const Singleton&){}; //禁止拷贝 Singleton& operator=(const Singleton&){}; //禁止赋值 static Singleton* instance1; }; Singleton* Singleton::instance1 = new Singleton(); //注意:静态成员应在类内声明,在类外初始化!!! |
- 享元模式 flyweight
运用共享技术有效地支持大量细粒度的对象。主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
- 外观模式 Façade
为子系统中的一组接口提供一个一致(稳定)的界面,facade模式定义了一个高层接口,这一接口使得这个子系统更加容易使用(复用)
- 代理模式 proxy pattern
为其他对象提供一种代理以控制(隔离,使用接口)对这个对象的访问。
- 适配器模式 adapter
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 中介模式 mediator
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 状态模式 state pattern
允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
#include <iostream> using namespace std; class Context; class State { public: virtual void Handle(Context *pContext) = 0; }; class StateA : public State { public: virtual void Handle(Context *pContext) { cout<<"I am concretestateA."<<endl; } }; class StateB : public State { public: virtual void Handle(Context *pContext) { cout<<"I am concretestateB."<<endl; } }; class Context { public: Context(State *pState) : m_pState(pState){} void Request() { if (m_pState) { m_pState->Handle(this); } } void ChangeState(State *pState) { m_pState = pState; } private: State *m_pState; }; int main() { State *pStateA = new StateA(); State *pStateB = new StateB(); Context *pContext = new Context(pStateA); pContext->Request(); pContext->ChangeState(pStateB); pContext->Request(); delete pContext; delete pStateB; delete pStateA; } |
- 备忘录 memento
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
#include <iostream> #include <string> using namespace std; class Memento { string state; public: Memento(const string& s):state(s){} string getState() const {return state;} void setState(const string& s){state = s;} }; class Originator { string state; public: Originator(string s):state(s){} Memento createMemento(){ Memento m(state); return m; } void changeState(string s){state = s;cout<<"当前状态:"<<state<<endl;}; void setMemento(const Memento& m){state = m.getState();cout<<"当前状态:"<<state<<endl;} }; int main() { Originator orig("123"); Memento mem = orig.createMemento(); orig.changeState("456"); //...改变orig状态 orig.setMemento(mem); return 0; } |
- 组合模式 composite
将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
#include <iostream> #include <string> #include <list> using namespace std; class Component { public: virtual void add(Component *element){} virtual void remove(Component *element){} virtual void process() = 0; virtual ~Component() {} }; class Composite : public Component { string name; list<Component *> elements; public: Composite(const string &s) : name(s) {} void add(Component *element){elements.push_back(element);} void remove(Component *element){elements.remove(element);} void process() { cout << "当前节点:" << name << endl; for (auto &e : elements) { e->process(); } } }; class Leaf : public Component { string name; public: Leaf(string s) : name(s) {} void process(){cout << "当前叶子节点:" << name << endl;} }; int main() { Component *proot = new Composite("root"); Component *ptreeNode1 = new Composite("treeNode1"); Component *ptreeNode2 = new Composite("treeNode2"); Component *ptreeNode3 = new Composite("treeNode3"); Component *ptreeNode4 = new Composite("treeNode4"); Component *pleaf1 = new Leaf("leaf1"); Component *pleaf2 = new Leaf("leaf2"); proot->add(ptreeNode1); ptreeNode1->add(ptreeNode2); ptreeNode2->add(pleaf1); proot->add(ptreeNode3); ptreeNode3->add(ptreeNode4); ptreeNode3->add(pleaf2); proot->process(); delete proot, ptreeNode1, ptreeNode2, ptreeNode3, ptreeNode4, pleaf1, pleaf2; return 0; } |
- 迭代器 iterator
提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
- 职责链 chain of responsibility
避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
#include <iostream> using namespace std; class Manager //抽象管理者 { protected: Manager *m_manager; string m_name; public: Manager(Manager *manager, string name) : m_manager(manager), m_name(name) {} virtual void DealWithRequest(string name, int num) {} }; class CommonManager : public Manager //经理 { public: CommonManager(Manager *manager, string name) : Manager(manager, name) {} void DealWithRequest(string name, int num) { if (num < 500) //经理职权之内 { cout << "经理[" << m_name << "]批准[" << name << "]加薪" << num << "元" << endl << endl; } else { cout << "经理[" << m_name << "]无法处理,交由总监处理" << endl; m_manager->DealWithRequest(name, num); } } }; class Majordomo : public Manager //总监 { public: Majordomo(Manager *manager, string name) : Manager(manager, name) {} void DealWithRequest(string name, int num) { if (num < 1000) //总监职权之内 { cout << "总监[" << m_name << "]批准[" << name << "]加薪" << num << "元" << endl << endl; } else { cout << "总监[" << m_name << "]无法处理,交由总经理处理" << endl; m_manager->DealWithRequest(name, num); } } }; class GeneralManager : public Manager //总经理 { public: GeneralManager(Manager *manager, string name) : Manager(manager, name) {} void DealWithRequest(string name, int num) //总经理可以处理所有请求 { cout << "总经理[" << m_name << "]批准[" << name << "]加薪" << num << "元" << endl << endl; } }; int main() { Manager *general = new GeneralManager(NULL, "张总"); //设置上级,总经理没有上级 Manager *major = new Majordomo(general, "王总监"); //设置上级 Manager *common = new CommonManager(major, "李经理"); //设置上级 common->DealWithRequest("小赵", 300); //员工要求加薪 common->DealWithRequest("小钱", 600); common->DealWithRequest("小孙", 1000); delete common, major, general; return 0; } |
- 命令模式 command
将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
#include <iostream> #include <string> #include <vector> using namespace std; class Barbecuer //烤肉师傅类,只负责烤串工作 { public: void BakeMutton() { cout << "烤串" << endl; } void BakeChickenWing() { cout << "烤鸡翅" << endl; } }; class Command //抽象命令类:是执行具体操作的接口 { public: Command(Barbecuer *receiver) : p_receiver(receiver) {} virtual void ExecuteCommand() = 0; //执行命令 protected: Barbecuer *p_receiver; }; class BakeMuttonCommand : public Command //具体命令类:烤羊肉串命令 { public: BakeMuttonCommand(Barbecuer *receiver) : Command(receiver) {} void ExecuteCommand() { p_receiver->BakeMutton(); } }; class BakeChickenWingCommand : public Command //具体命令类:烤鸡翅串命令 { public: BakeChickenWingCommand(Barbecuer *receiver) : Command(receiver) {} void ExecuteCommand() { p_receiver->BakeChickenWing(); } }; class Waiter //服务员 { public: void SetOrder(Command *command) //接收命令 { p_commandList.push_back(command); cout << "增加烤肉命令" << endl; } void Notify() //做出反应 { for (auto i = p_commandList.begin(); i != p_commandList.end(); ++i) { (*i)->ExecuteCommand(); } } private: vector<Command *> p_commandList; //这里相当于一个命令对象队列 }; int main(int argc, char *argv[]) { //生成烤肉师傅、服务员、订单对象 Barbecuer *p_cook = new Barbecuer(); Command *p_mutton = new BakeMuttonCommand(p_cook); Command *p_chickenwing = new BakeChickenWingCommand(p_cook); Waiter *p_waiter = new Waiter(); //将订单对象推送到命令队列 p_waiter->SetOrder(p_mutton); p_waiter->SetOrder(p_chickenwing); //服务员通知烤肉师傅具体订单 p_waiter->Notify(); delete p_cook, p_mutton, p_chickenwing, p_waiter; return 0; } |
- 访问器 visitor
使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
#include <iostream> using namespace std; class Visitor; class Element { public: virtual void accept(Visitor &visitor) = 0; //第一次多态辨析(找accept) virtual ~Element() {} }; class ElementA : public Element { public: virtual void accept(Visitor &visitor) override; //第二次多态辨析(找visitElementA) }; class ElementB : public Element { public: void accept(Visitor &visitor) override; }; class Visitor { public: virtual void visitElementA(ElementA &element) = 0; virtual void visitElementB(ElementB &element) = 0; virtual ~Visitor() {} }; void ElementA::accept(Visitor &visitor) { visitor.visitElementA(*this); //第二次多态辨析(找visitElementA) } void ElementB::accept(Visitor &visitor) { visitor.visitElementB(*this); } //======上面代码是稳定的,下面代码是变化的========= //对行为进行更改 class Visiter1 : public Visitor { public: void visitElementA(ElementA &element) override { cout << "Visitor1 process ElementA" << endl; } void visitElementB(ElementB &element) override { cout << "Visitor1 process ElementB" << endl; } }; class Visiter2 : public Visitor { public: void visitElementA(ElementA &element) override { cout << "Visitor2 process ElementA" << endl; } void visitElementB(ElementB &element) override { cout << "Visitor2 process ElementB" << endl; } }; int main() { Visiter1 visitor; ElementA elementA; elementA.accept(visitor); //二次多态辨析 ElementB elementB; elementB.accept(visitor); return 0; } |
- 解析器 interpreter
给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
#include <iostream> #include <map> #include <stack> #include <vector> using namespace std; class Expression { public: virtual int interpreter(map<char, int> var) = 0; virtual ~Expression() {} }; //变量表达式 class VarExpression : public Expression { char key; public: VarExpression(const char &key) { this->key = key; } int interpreter(map<char, int> var) override { return var[key]; } }; //符号表达式 class SymbolExpression : public Expression { // 运算符左右两个参数 protected: Expression *left; Expression *right; public: SymbolExpression(Expression *left, Expression *right) : left(left), right(right) {} }; //加法运算 class AddExpression : public SymbolExpression { public: AddExpression(Expression *left, Expression *right) : SymbolExpression(left, right) {} int interpreter(map<char, int> var) override { return left->interpreter(var) + right->interpreter(var); } }; //减法运算 class SubExpression : public SymbolExpression { public: SubExpression(Expression *left, Expression *right) : SymbolExpression(left, right) {} int interpreter(map<char, int> var) override { return left->interpreter(var) - right->interpreter(var); } }; vector<Expression *> tobeRelease; Expression *analyse(const string &expStr) { stack<Expression *> expStack; Expression *left = nullptr; Expression *right = nullptr; for (int i = 0; i < expStr.size(); i++) { switch (expStr[i]) { case '+': // 加法运算 left = expStack.top(); right = new VarExpression(expStr[++i]); expStack.push(new AddExpression(left, right)); tobeRelease.push_back(right); break; case '-': // 减法运算 left = expStack.top(); right = new VarExpression(expStr[++i]); expStack.push(new SubExpression(left, right)); tobeRelease.push_back(right); break; default: // 变量表达式 expStack.push(new VarExpression(expStr[i])); } tobeRelease.push_back(expStack.top()); } Expression *expression = expStack.top(); return expression; } int main() { string expStr = "a+b-c+d-e"; map<char, int> var; var.insert(make_pair('a', 5)); var.insert(make_pair('b', 2)); var.insert(make_pair('c', 1)); var.insert(make_pair('d', 6)); var.insert(make_pair('e', 10)); Expression *expression = analyse(expStr); int result = expression->interpreter(var); cout << result << endl; for (auto &x : tobeRelease) { delete x; } return 0; } |

浙公网安备 33010602011771号