- 行为型模式,共十一种:
-
模板方法模式
- 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。我们的例子中,操作就是填写简历这一过程,我们可以在父类中定义操作的算法骨架,而具体的实现由子类完成。
//简历 class Resume { protected: //保护成员 virtual void SetPersonalInfo() {} virtual void SetEducation() {} virtual void SetWorkExp() {} public: void FillResume() { SetPersonalInfo(); SetEducation(); SetWorkExp(); } }; class ResumeA: public Resume { protected: void SetPersonalInfo() { cout<<"A's PersonalInfo"<<endl; } void SetEducation() { cout<<"A's Education"<<endl; } void SetWorkExp() { cout<<"A's Work Experience"<<endl; } }; class ResumeB: public Resume { protected: void SetPersonalInfo() { cout<<"B's PersonalInfo"<<endl; } void SetEducation() { cout<<"B's Education"<<endl; } void SetWorkExp() { cout<<"B's Work Experience"<<endl; } }; int main() { Resume *r1; r1 = new ResumeA(); r1->FillResume(); delete r1; r1 = new ResumeB(); r1->FillResume(); delete r1; r1 = NULL; return 0; }
- 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。我们的例子中,操作就是填写简历这一过程,我们可以在父类中定义操作的算法骨架,而具体的实现由子类完成。
-
迭代子模式
-
责任链模式
- 职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。其思想很简单,考虑员工要求加薪。公司的管理者一共有三级,总经理、总监、经理,如果一个员工要求加薪,应该向主管的经理申请,如果加薪的数量在经理的职权内,那么经理可以直接批准,否则将申请上交给总监。总监的处理方式也一样,总经理可以处理所有请求。这就是典型的职责链模式,请求的处理形成了一条链,直到有一个对象处理请求。
//抽象管理者 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, "A"); //设置上级,总经理没有上级 Manager *majordomo = new Majordomo(general, "B"); //设置上级 Manager *common = new CommonManager(majordomo, "C"); //设置上级 common->DealWithRequest("D",300); //员工D要求加薪 common->DealWithRequest("E", 600); common->DealWithRequest("F", 1000); delete common; delete majordomo; delete general; return 0; }
-
策略模式
- 策略模式是指定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也就是说这些算法所完成的功能一样,对外的接口一样,只是各自实现上存在差异。用策略模式来封装算法,效果比较好。
//抽象接口 class ReplaceAlgorithm { public: virtual void Replace() = 0; }; //三种具体的替换算法 class LRU_ReplaceAlgorithm : public ReplaceAlgorithm { public: void Replace() { cout<<"Least Recently Used replace algorithm"<<endl; } }; class FIFO_ReplaceAlgorithm : public ReplaceAlgorithm { public: void Replace() { cout<<"First in First out replace algorithm"<<endl; } }; class Random_ReplaceAlgorithm: public ReplaceAlgorithm { public: void Replace() { cout<<"Random replace algorithm"<<endl; } }; //Cache需要用到替换算法 template <class RA> class Cache { private: RA m_ra; public: Cache() { } ~Cache() { } void Replace() { m_ra.Replace(); } }; int main() { Cache<Random_ReplaceAlgorithm> cache; //模板实参 cache.Replace(); return 0; }
-
状态模式
- 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。属于行为型模式。
#include<iostream> #include<string> #include<vector> using namespace std; class Context; //创建一个状态接口State抽象类 class State { public: State() {}; ~State() {}; virtual void doAction(Context *tcontext)=0; virtual string toString()=0; }; //创建实现State接口的实体类StartState。 class StartState :public State { public: StartState() {}; ~StartState() {}; void doAction(Context *tcontext); string toString(); }; string StartState::toString() { return "Start State"; } //创建实现State接口的实体类StopState。 class StopState :public State { public: StopState() {}; ~StopState() {}; void doAction(Context *tcontext); string toString(); }; string StopState::toString() { return "Stop State"; } //创建Context类。 class Context { public: Context() {}; ~Context() {}; void setState(State *tstate); State *getState(); private: State *mstate; }; void Context::setState(State *tstate) { this->mstate = tstate; } State *Context::getState() { return mstate; } void StartState::doAction(Context *tcontext) { cout << "Player is in start state" << endl; tcontext->setState(this); } void StopState::doAction(Context *tcontext) { cout << "Player is in stop state" << endl; tcontext->setState(this); } int main() { Context *contexts = new Context(); StartState *startstates = new StartState(); startstates->doAction(contexts); cout << contexts->getState()->toString() << endl; StopState *stopstates = new StopState(); stopstates->doAction(contexts); cout << contexts->getState()->toString() << endl; system("pause"); return 0; }
- 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。属于行为型模式。
-
备忘录模式
- 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态[DP]。举个简单的例子,我们玩游戏时都会保存进度,所保存的进度以文件的形式存在。这样下次就可以继续玩,而不用从头开始。这里的进度其实就是游戏的内部状态,而这里的文件相当于是在游戏之外保存状态。这样,下次就可以从文件中读入保存的进度,从而恢复到原来的状态。这就是备忘录模式。
//需保存的信息 class Memento { public: int m_vitality; //生命值 int m_attack; //进攻值 int m_defense; //防守值 public: Memento(int vitality, int attack, int defense): m_vitality(vitality),m_attack(attack),m_defense(defense){} Memento& operator=(const Memento &memento) { m_vitality = memento.m_vitality; m_attack = memento.m_attack; m_defense = memento.m_defense; return *this; } }; //游戏角色 class GameRole { private: int m_vitality; int m_attack; int m_defense; public: GameRole(): m_vitality(100),m_attack(100),m_defense(100) {} Memento Save() //保存进度,只与Memento对象交互,并不牵涉到Caretake { Memento memento(m_vitality, m_attack, m_defense); return memento; } void Load(Memento memento) //载入进度,只与Memento对象交互,并不牵涉到Caretake { m_vitality = memento.m_vitality; m_attack = memento.m_attack; m_defense = memento.m_defense; } void Show() { cout<<"vitality : "<< m_vitality<<", attack : "<< m_attack<<", defense : "<< m_defense<<endl; } void Attack() { m_vitality -= 10; m_attack -= 10; m_defense -= 10; } }; //保存的进度库 class Caretake { public: Caretake() {} void Save(Memento menento) { m_vecMemento.push_back(menento); } Memento Load(int state) { return m_vecMemento[state]; } private: vector<Memento> m_vecMemento; }; //测试案例 int main() { Caretake caretake; GameRole role; role.Show(); //初始值 caretake.Save(role.Save()); //保存状态 role.Attack(); role.Show(); //进攻后 role.Load(caretake.Load(0)); //载入状态 role.Show(); //恢复到状态0 return 0; }
-
中介者模式
- 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式的例子很多,大到联合国安理会,小到房屋中介,都扮演了中间者的角色,协调各方利益。
class Mediator; //抽象人 class Person { protected: Mediator *m_mediator; //中介 public: virtual void SetMediator(Mediator *mediator){} //设置中介 virtual void SendMessage(string message) {} //向中介发送信息 virtual void GetMessage(string message) {} //从中介获取信息 }; //抽象中介机构 class Mediator { public: virtual void Send(string message, Person *person) {} virtual void SetA(Person *A) {} //设置其中一方 virtual void SetB(Person *B) {} }; //租房者 class Renter: public Person { public: void SetMediator(Mediator *mediator) { m_mediator = mediator; } void SendMessage(string message) { m_mediator->Send(message, this); } void GetMessage(string message) { cout<<"租房者收到信息"<<message; } }; //房东 class Landlord: public Person { public: void SetMediator(Mediator *mediator) { m_mediator = mediator; } void SendMessage(string message) { m_mediator->Send(message, this); } void GetMessage(string message) { cout<<"房东收到信息:"<<message; } }; //房屋中介 class HouseMediator : public Mediator { private: Person *m_A; //租房者 Person *m_B; //房东 public: HouseMediator(): m_A(0), m_B(0) {} void SetA(Person *A) { m_A = A; } void SetB(Person *B) { m_B = B; } void Send(string message, Person *person) { if(person == m_A) //租房者给房东发信息 m_B->GetMessage(message); //房东收到信息 else m_A->GetMessage(message); } }; //测试案例 int main() { Mediator *mediator = new HouseMediator(); Person *person1 = new Renter(); //租房者 Person *person2 = new Landlord(); //房东 mediator->SetA(person1); mediator->SetB(person2); person1->SetMediator(mediator); person2->SetMediator(mediator); person1->SendMessage("我想在南京路附近租套房子,价格800元一个月\n"); person2->SendMessage("出租房子:南京路100号,70平米,1000元一个月\n"); delete person1; delete person2; delete mediator; return 0; }
-
命令模式
- 将请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
#include<iostream> #include<string> #include<list> using namespace std; //创建命令接口Order类 class Order { public: Order() {}; virtual ~Order() {}; virtual void execute()=0; //抽象接口,执行命令 }; //创建一个请求类Stock class Stock { public: Stock(string tname, int quanty); ~Stock() {}; void buy(); void sell(); private: string name; int quantity; }; Stock::Stock(string tname, int quanty) { this->name = tname; this->quantity = quanty; } void Stock::buy() { cout << "Stock [ Name: " << name << " ,Quantity: " << quantity << " bought" << endl; } void Stock::sell() { cout << "Stock [ Name: " << name << " ,Quantity: " << quantity << " sold" << endl; } //创建实现命令接口的实体类BuyStock class BuyStock :public Order { public: BuyStock(Stock *abcStock); ~BuyStock() {}; void execute(); private: Stock *abcstock; //请求类成员变量 }; BuyStock::BuyStock(Stock *abcStock) { this->abcstock = abcStock; } void BuyStock::execute() { abcstock->buy(); } //创建实现命令接口的实体类SellStock class SellStock :public Order { public: SellStock(Stock *abcStock); ~SellStock() {}; void execute(); private: Stock *abcstock; }; SellStock::SellStock(Stock *abcStock) { this->abcstock = abcStock; } void SellStock::execute() { abcstock->sell(); } //命令调用类Broker class Broker { public: Broker() {}; ~Broker() {} ; void takeOrder(Order *torder); void placeOrder(); private: list<Order*> orderlist; //命令列表 }; void Broker::takeOrder(Order *torder) { orderlist.push_back(torder); } void Broker::placeOrder() { list<Order*>::iterator it; for (it = orderlist.begin(); it != orderlist.end(); ++it) { (*it)->execute(); } orderlist.clear(); } int main() { Stock *tbcstock = new Stock("ADE", 10); Order *buystock =(Order *) new BuyStock(tbcstock); Order *sellstock =(Order *)new SellStock(tbcstock); Broker *broker =new Broker(); broker->takeOrder(buystock); broker->takeOrder(sellstock); broker->placeOrder(); delete tbcstock; tbcstock = NULL; delete buystock; buystock = NULL; delete sellstock; sellstock = NULL; delete broker; broker = NULL; system("pause"); return 0; }
- 将请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
-
访问者模式
-
观察者模式
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。它还有两个别名,依赖(Dependents),发布-订阅(Publish-Subsrcibe)。可以举个博客订阅的例子,当博主发表新文章的时候,即博主状态发生了改变,那些订阅的读者就会收到通知,然后进行相应的动作,比如去看文章,或者收藏起来。博主与读者之间存在种一对多的依赖关系
//观察者 class Observer { public: Observer() {} virtual ~Observer() {} virtual void Update() {} }; //博客 class Blog { public: Blog() {} virtual ~Blog() {} void Attach(Observer *observer) { m_observers.push_back(observer); } //添加观察者 void Remove(Observer *observer) { m_observers.remove(observer); } //移除观察者 void Notify() //通知观察者 { list<Observer*>::iterator iter = m_observers.begin(); for(; iter != m_observers.end(); iter++) (*iter)->Update(); } virtual void SetStatus(string s) { m_status = s; } //设置状态 virtual string GetStatus() { return m_status; } //获得状态 private: list<Observer* > m_observers; //观察者链表 protected: string m_status; //状态 }; //具体博客类 class BlogCSDN : public Blog { private: string m_name; //博主名称 public: BlogCSDN(string name): m_name(name) {} ~BlogCSDN() {} void SetStatus(string s) { m_status = "CSDN通知 : " + m_name + s; } //具体设置状态信息 string GetStatus() { return m_status; } }; //具体观察者 class ObserverBlog : public Observer { private: string m_name; //观察者名称 Blog *m_blog; //观察的博客,当然以链表形式更好,就可以观察多个博客 public: ObserverBlog(string name,Blog *blog): m_name(name), m_blog(blog) {} ~ObserverBlog() {} void Update() //获得更新状态 { string status = m_blog->GetStatus(); cout<<m_name<<"-------"<<status<<endl; } }; //测试案例 int main() { Blog *blog = new BlogCSDN("wuzhekai1985"); Observer *observer1 = new ObserverBlog("tutupig", blog); blog->Attach(observer1); blog->SetStatus("发表设计模式C++实现(15)——观察者模式"); blog->Notify(); delete blog; delete observer1; return 0; }
-
解释器模式
- 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。常被用在 SQL 解析、符号处理引擎
#include<iostream> #include<string> using namespace std; //创建一个表达式抽象接口类Expression class Expression { public: Expression() {}; virtual ~Expression() {}; virtual bool interpret(string context)=0; }; //创建实现了抽象接口Expression的实体类TerminalExpression class TerminalExpression :public Expression { public: TerminalExpression(string data); ~TerminalExpression() {}; bool interpret(string context); private: string data; }; TerminalExpression::TerminalExpression(string data) { this->data = data; } bool TerminalExpression::interpret(string context) { if (context.find(data) != string::npos) { return true; } return false; } //创建实现了抽象接口Expression的实体类OrExpression class OrExpression :public Expression { public: OrExpression(Expression *texpr1, Expression *texpr2); ~OrExpression() {}; bool interpret(string context); private: Expression *expr1; Expression *expr2; }; OrExpression::OrExpression(Expression *texpr1, Expression *texpr2) { this->expr1 = texpr1; this->expr2 = texpr2; } bool OrExpression::interpret(string context) { if (expr1->interpret(context)|| expr2->interpret(context)) { return true; } return false; } //创建实现了抽象接口Expression的实体类AndExpression class AndExpression :public Expression { public: AndExpression(Expression *texpr1, Expression *texpr2); ~AndExpression() {}; bool interpret(string context); private: Expression *expr1; Expression *expr2; }; AndExpression::AndExpression(Expression *texpr1, Expression *texpr2) { this->expr1 = texpr1; this->expr2 = texpr2; } bool AndExpression::interpret(string context) { if (expr1->interpret(context) && expr2->interpret(context)) { return true; } return false; } int main() { //规则:Robert 和 John 是男性 Expression *robert =(Expression *) new TerminalExpression("Robert"); Expression *john = (Expression *) new TerminalExpression("John"); Expression *isMale = (Expression *)new OrExpression(robert, john); //规则:Julie 是一个已婚的女性 Expression *julie = (Expression *) new TerminalExpression("Julie"); Expression *married = (Expression *) new TerminalExpression("Married"); Expression *isMarriedWoman = (Expression *) new AndExpression(julie, married); string result1 = (isMale->interpret("John")) ? "true" : "false"; cout << "John is male? " << result1 << endl; string result2 = (isMarriedWoman->interpret("Married Julie")) ? "true" : "false"; cout << "Julie is a married women? " << result2 << endl; delete robert; robert = NULL; delete john; john = NULL; delete isMale; isMale = NULL; delete julie; julie = NULL; delete married; married = NULL; delete isMarriedWoman; isMarriedWoman = NULL; system("pause"); return 0; }
-