访问者模式
访问者模式可以将算法与其操作的对象类进行解耦。这种模式通过构建一个新的Visitor类,以防止新功能被整合进已有的类中(至少以更小的代价被整合进已有类中)。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364class Shape { public: virtual void move(int x, int y) = 0; virtual void draw() = 0; virtual void accept(Visitor* v) = 0; virtual ~Shape() {}};class Dot: public Shape { // ... void accept(Visitor* v) override { v->visitDot(this); }};class Ci ...
模板模式
模板方法允许程序员实现一种算法骨架,在具体算法中实现骨架中的每个具体步骤而不改变骨架本身。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849class GameAI { public: std::vector<Structure*> builtStructures; void turn() { collectResources(); buildStructures(); buildUnits(); attack(); } void collectResources() { for (Structure* s: builtStructures) { s->collect(); } } virtual buildStructures() = 0; virtual ...
状态机模式
状态机模式允许一个类在内部状态发生变化时更改其行为,仿佛它转变为另一个类一样。状态机模式与有限状态机密切相关。
通常的状态机实现随着类所能具有的状态数量增加而显著增加。状态机模式建议将所有所有模式转化为不同的类,并将所有与状态有关的操作封装在这些类当中。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788class AudioPlayer { public: State* state; Song* currentSong; int volume; AudioPlayer() { state = new ReadyState(this); } ~AudioPlayer() { if (state) delete ...
观察者模式
观察者模式是一种订阅机制:观察者对象可以第一时间收到其观察对象变化的通知
一个包含所有订阅者对象的表
几个用于订阅和取消订阅的方法
必要时,被订阅者将遍历订阅表,并调用每个观察者的特定方法以通知对应的观察者。
总结起来,观察者模式有一个EventManager,通过它维护订阅关系。消息发布者调用其notify方法,来通知所有订阅者。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990#include <vector>#include <string>#include <map>class EventManager { private: std::map<std::string, std::vector<EventListener* ...
备忘录模式
允许在不暴露对象实现细节的情况下,将对象恢复到之前的状态。
快照对象应该是不可变对象,仅被初始化一次
快照发起者可以实现restore(Momento* m)方法,也可以由快照实现restore()方法。后者可以将快照对象与照看者对象(CareTaker)解耦。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354class Editor { private: std::string text; int curX, curY, selectionWidth; public: void setText(std::string t) { text = t; } void setCursor(int x, int y) { curX = x; curY = y; } void setSelectionWdith(int ...
中介者模式
组件之间存在复杂依赖的时候,可以构造一个中介者统一管理组件之间的通讯。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960class Mediator { public: virtual ~Mediator() {} virtual void notify(Component* sender, std::string event) = 0; };class AuthenticationDialog: public Mediator { private: std::string title; Checkbox *loginOrRegisterChkBx; Textbox *loginUsername, *loginPassword; Textbox *registrationUsername, *registrationPassw ...
迭代器模式
迭代器模式用于访问组合对象。迭代器知晓组合对象的内部结构,将迭代的实现细节屏蔽在迭代器内部,而组合对象本身不负责遍历。
迭代器模式允许外部遍历整个对象而不暴露组合对象的内部实现。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970class SocialNetwork { public: virtual ProfileIterator* createFriendsIterator(int profileId) const = 0; virtual ProfileIterator* createCoworkersIterator(int profileId) const = 0; virtual ~SocialNetwork() {}};class Facebook: public SocialNetwork { ...
命令模式
把请求封装成一个对象,从而分离请求发起和执行。发起者和执行者之间通过命令对象进行沟通,便于请求对象的储存、传递、调用、增加和管理。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115class Command { protected: Application* app_; Editor* editor_; std::string backup_; public: Command(Application* app, Editor* editor): app_(app), editor_(editor) {} ...
责任链模式
通常而言,责任链模式涉及到一个共同的接口或抽象类,各个实际处理类继承该接口并持有下一个处理器的引用。
但是下面这个例子将给出一个在GUI设计中的特殊责任链实现模式,通过子组件对父组件的继承关系自然形成引用。下面的设计通过Container* container指针实现了链路,同时,向上传递的过程被抽象出来,安插在Component类中。
这种实现方式是将所有业务逻辑全部包含在类内部的思路,它更加清晰,但同时也缺乏可扩展性。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253class ComponentWithContextualHelp { public: virtual void showHelp() const = 0; virtual ~ComponentWithContextualHelp() {}};class Component: public ComponentWithC ...
享元模式
flyweight pattern
实例的属性可分为两种:
内在状态intrinsic state:可以被共享的状态
外在状态extrinsic state:不可被共享的状态,经常被外部实例更改
享元模式的本质是,抽取公共属性作为单独的类,以静态形式存储。每个实例都拥有这个公共属性的指针。也即“共享”一部分“元数据”。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647class TreeType { std::string name_; std::string color_; std::string texture_; public: TreeType(std::string name, std::string color, Texture texture): name_(name), color_(color), texture_(texture) {} void draw(const Canvas& ...