设计模式-04-行为型模式详解
2018-02-28 23:34
483 查看
承接上一篇博客设计模式-03-结构型模式详解,本篇讨论结构型模式的相关内容
命令模式把请求一个操作的对象与知道怎么操行一个操作的对象分开
为遍历不同的聚集结构提供如开始,下一个,是否结束,当前一项等统一接口。
适用于功能比较复杂的,但需要记录或维护属性历史的类;或者需要保存的属性只是众多属性中的一小部分时Originator可以根据保存的Memo还原到前一状态。
适合类中的成员以方法为主,算法经常变动;简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试。
策略模式和简单工厂基本相同,但简单工厂模式只能解决对象创建问题,对于经常变动的算法应使用策略模式。
新增加操作很容易,因为增加新操作就相当于增加一个访问者,访问者模式将有关的行为集中到一个访问者对象中
一.责任链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理为止。代码举例:
#include <iostream> #include <string> #include <vector> using namespace std; //请求 class Request { public: string m_strContent; int m_nNumber; }; //管理者 class Manager { protected: Manager* manager; string name; public: Manager(string temp) { name = temp; } void SetSuccessor(Manager* temp) { manager = temp; } virtual void GetRequest(Request* request) = 0; }; //经理 class CommonManager : public Manager { public: CommonManager(string strTemp) : Manager(strTemp){} virtual void GetRequest(Request* request) { if ( request->m_nNumber>=0 && request->m_nNumber<10 ) { cout<<name<<"处理了"<<request->m_nNumber<<"个请求"<<endl; } else { manager->GetRequest(request); } } }; //总监 class MajorDomo : public Manager { public: MajorDomo(string name) : Manager(name){} virtual void GetRequest(Request* request) { if(request->m_nNumber>=10) { cout<<name<<"处理了"<<request->m_nNumber<<"个请求"<<endl; } } }; //客户端 int main() { Manager * common = new CommonManager("张经理"); Manager * major = new MajorDomo("李总监"); common->SetSuccessor(major); Request* req = new Request(); req->m_nNumber = 33; common->GetRequest(req); req->m_nNumber = 3; common->GetRequest(req); return 0; }
二.命令模式
一、建立命令队列;二、可以将命令记入日志;三、接收请求的一方可以拒绝;四、添加一个新命令类不影响其它类;命令模式把请求一个操作的对象与知道怎么操行一个操作的对象分开
代码举例:
#include <iostream> #include <string> #include <vector> using namespace std; //烤肉师傅 class Barbucer { public: void MakeMutton() { cout<<"烤羊肉"<<endl; } void MakeChickenWing() { cout<<"烤鸡翅膀"<<endl; } }; //抽象命令类 class Command { protected: Barbucer* receiver; public: Command(Barbucer* temp) { receiver = temp; } virtual void ExecuteCmd()=0; }; //烤羊肉命令 class BakeMuttonCmd : public Command { public: BakeMuttonCmd(Barbucer* temp) : Command(temp){} virtual void ExecuteCmd() { receiver->MakeMutton(); } }; //烤鸡翅 class ChickenWingCmd : public Command { public: ChickenWingCmd(Barbucer* temp) : Command(temp){} virtual void ExecuteCmd() { receiver->MakeChickenWing(); } }; //服务员类 class Waiter { protected: vector<Command*> m_commandList; public: void SetCmd(Command* temp) { m_commandList.push_back(temp); cout<<"增加定单"<<endl; } //通知执行 void Notify() { vector<Command*>::iterator p=m_commandList.begin(); while(p!=m_commandList.end()) { (*p)->ExecuteCmd(); p++; } } }; //客户端 int main() { //店里添加烤肉师傅、菜单、服务员等顾客 Barbucer* barbucer=new Barbucer(); Command* cmd= new BakeMuttonCmd(barbucer); Command* cmd2=new ChickenWingCmd(barbucer); Waiter* girl = new Waiter(); //点菜 girl->SetCmd(cmd); girl->SetCmd(cmd2); //服务员通知 girl->Notify(); return 0; }
三.解释器模式
通常当一个语言需要解释执行,并且你可以将该语言中的句子表示成为一个抽象的语法树时,可以使用解释器模式。代码举例:
#include <iostream> #include <string> #include <vector> using namespace std; class Context; class AbstractExpression { public: virtual void Interpret(Context* context)=0; }; class Expression : public AbstractExpression { public: virtual void Interpret(Context* context) { cout<<"终端解释器"<<endl; }; }; class NonterminalExpression : public AbstractExpression { public: virtual void Interpret(Context* context) { cout<<"非终端解释器"<<endl; } }; class Context { public: string input; string output; }; //客户端 int main() { Context* context = new Context(); vector<AbstractExpression*> express; express.push_back(new Expression()); express.push_back(new NonterminalExpression()); express.push_back(new NonterminalExpression()); vector<AbstractExpression*>::iterator p = express.begin(); while (p!= express.end()) { (*p)->Interpret(context); p++; } return 0; }
四.迭代器模式
提供一种方法顺序访问一个聚敛对象的各个元素,而又不暴露该对象的内部表示。为遍历不同的聚集结构提供如开始,下一个,是否结束,当前一项等统一接口。
五.中介者模式
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示的相互引用,从而降低耦合;而且可以独立地改变它们之间的交互。代码举例:
#include <iostream> #include <string> #include <vector> using namespace std; class Colleague; //中介者类 class Mediator { public: virtual void Send(string message,Colleague* col) = 0; }; //抽象同事类 class Colleague { protected: Mediator* mediator; public: Colleague(Mediator* temp) { mediator = temp; } }; //同事一 class Colleague1 : public Colleague { public: Colleague1(Mediator* media) : Colleague(media){} void Send(string strMessage) { mediator->Send(strMessage,this); } void Notify(string strMessage) { cout<<"同事一获得了消息"<<strMessage<<endl; } }; //同事二 class Colleague2 : public Colleague { public: Colleague2(Mediator* media) : Colleague(media){} void Send(string strMessage) { mediator->Send(strMessage,this); } void Notify(string strMessage) { cout<<"同事二获得了消息"<<strMessage<<endl; } }; //具体中介者类 class ConcreteMediator : public Mediator { public: Colleague1 * col1; Colleague2 * col2; virtual void Send(string message,Colleague* col) { if(col == col1) col2->Notify(message); else col1->Notify(message); } }; //客户端: int main() { ConcreteMediator * m = new ConcreteMediator(); //让同事认识中介 Colleague1* col1 = new Colleague1(m); Colleague2* col2 = new Colleague2(m); //让中介认识具体的同事类 m->col1 = col1; m->col2 = col2; col1->Send("吃饭了吗?"); col2->Send("还没吃,你请吗?"); return 0; }
六.备忘录模式
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以将以后的对象状态恢复到先前保存的状态。适用于功能比较复杂的,但需要记录或维护属性历史的类;或者需要保存的属性只是众多属性中的一小部分时Originator可以根据保存的Memo还原到前一状态。
代码举例:
#include <iostream> #include <string> using namespace std; class Memo; //发起人类 class Originator { public: string state; Memo* CreateMemo(); void SetMemo(Memo* memo); void Show() { cout<<"状态:"<<state<<endl; } }; //备忘录类 class Memo { public: string state; Memo(string strState) { state= strState; } }; Memo* Originator::CreateMemo() { return new Memo(state); } void Originator::SetMemo(Memo* memo) { state = memo->state; } //管理者类 class Caretaker { public: Memo* memo; }; 客户端: int main() { Originator* on=new Originator(); on->state = "on"; on->Show(); Caretaker* c= new Caretaker(); c->memo = on->CreateMemo(); on->state = "off"; on->Show(); on->SetMemo(c->memo); on->Show(); return 0; }
七.观察者模式
定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。代码举例:
#include <string> #include <iostream> #include <vector> using namespace std; class Secretary; //看股票的同事类(观察对象,观察者) class StockObserver { private: string name; Secretary* sub; public: StockObserver(string strname,Secretary* strsub) { name=strname; sub=strsub; } void Update(); }; //秘书类(主题对象,通知者) class Secretary { private: vector<StockObserver> observers; public: string action; void Add(StockObserver ob) { observers.push_back(ob); } void Notify() { vector<StockObserver>::iterator p = observers.begin(); while (p!=observers.end()) { (*p).Update(); p++; } } }; void StockObserver::Update() { cout<<name<<":"<<sub->action<<",不要玩股票了,要开始工作了"<<endl; } //客户端 int main() { Secretary *p=new Secretary(); //创建通知者 //观察者 StockObserver *s1= new StockObserver("小李",p); StockObserver *s2 = new StockObserver("小赵",p); //加入通知队列 p->Add(*s1); p->Add(*s2); //事件 p->action="老板来了"; //通知 p->Notify(); return 0; }
八.状态模式
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,可考虑用到状态模式。代码举例:
#include <iostream> using namespace std; class Work; class ForenoonState; class NoonState; class State { public: virtual void WriteProgram(Work* w)=0; }; class Work { private: State* current; public: double hour; public: Work(); void SetState(State* temp) { current =temp; } void Writeprogram() { current->WriteProgram(this); } }; class NoonState :public State { public: virtual void WriteProgram(Work* w) { cout<<"execute"<<endl; if((w->hour)<13) cout<<"还不错啦"<<endl; else cout<<"不行了,还是睡觉吧"<<endl; } }; class ForenoonState : public State { public: virtual void WriteProgram(Work* w) { if((w->hour)<12) cout<<"现在的精神无敌好"<<endl; else { w->SetState(new NoonState()); w->Writeprogram(); //注意加上这句 } } }; Work::Work() { current = new ForenoonState(); } 客户端: int main() { Work* mywork=new Work(); mywork->hour=9; mywork->Writeprogram(); mywork->hour = 14; mywork->Writeprogram(); return 0; }
九.策略模式
定义算法家族,分别封装起来,让它们之间可以互相替换,让算法变化,不会影响到用户适合类中的成员以方法为主,算法经常变动;简化了单元测试(因为每个算法都有自己的类,可以通过自己的接口单独测试。
策略模式和简单工厂基本相同,但简单工厂模式只能解决对象创建问题,对于经常变动的算法应使用策略模式。
代码举例:
//策略基类 class COperation { public: int m_nFirst; int m_nSecond; virtual double GetResult() { double dResult=0; return dResult; } }; //策略具体类—加法类 class AddOperation : public COperation { public: AddOperation(int a,int b) { m_nFirst=a; m_nSecond=b; } virtual double GetResult() { return m_nFirst+m_nSecond; } }; class Context { private: COperation* op; public: Context(COperation* temp) { op=temp; } double GetResult() { return op->GetResult(); } }; //客户端 int main() { int a,b; char c; cin>>a>>b; cout<<”请输入运算符:; cin>>c; switch(c) { case ‘+’: Context *context=new Context(new AddOperation(a,b)); cout<<context->GetResult()<<endl; break; default: break; } return 0; }
十.模板模式
把不变的代码部分都转移到父类中,将可变的代码用virtual留到子类重写代码举例:
#include<iostream> #include <vector> #include <string> using namespace std; class AbstractClass { public: void Show() { cout<<"我是"<<GetName()<<endl; } protected: virtual string GetName()=0; }; class Naruto : public AbstractClass { protected: virtual string GetName() { return "火影史上最帅的六代目---一鸣惊人naruto"; } }; class OnePice : public AbstractClass { protected: virtual string GetName() { return "我是无恶不做的大海贼---路飞"; } }; //客户端 int main() { Naruto* man = new Naruto(); man->Show(); OnePice* man2 = new OnePice(); man2->Show(); return 0; }
十一.访问者模式
适用于数据结构稳定的系统。它把数据结构和作用于数据结构上的操作分离开,使得操作集合新增加操作很容易,因为增加新操作就相当于增加一个访问者,访问者模式将有关的行为集中到一个访问者对象中
代码举例:
#include <iostream> #include <string> #include <vector> using namespace std; class Man; class Woman; //行为 class Action { public: virtual void GetManConclusion(Man* concreteElementA)=0; virtual void GetWomanConclusion(Woman* concreteElementB)=0; }; //成功 class Success : public Action { public: virtual void GetManConclusion(Man* concreteElementA) { cout<<"男人成功时,背后有个伟大的女人"<<endl; } virtual void GetWomanConclusion(Woman* concreteElementB) { cout<<"女人成功时,背后有个没用的男人"<<endl; } }; //失败 class Failure : public Action { public: virtual void GetManConclusion(Man* concreteElementA) { cout<<"男人失败时,背后有个伟大的女人"<<endl; } virtual void GetWomanConclusion(Woman* concreteElementB) { cout<<"女人失败时,背后有个没用的男人"<<endl; } }; //抽象人类 class Person { public: virtual void Accept(Action* visitor)=0; }; //男人 class Man : public Person { public: virtual void Accept(Action* visitor) { visitor->GetManConclusion(this); } }; //女人 class Woman : public Person { public: virtual void Accept(Action* visitor) { visitor->GetWomanConclusion(this); } }; //对象结构类 class ObjectStructure { private: vector<Person*> m_personList; public: void Add(Person* p) { m_personList.push_back(p); } void Display(Action* a) { vector<Person*>::iterator p = m_personList.begin(); while (p!=m_personList.end()) { (*p)->Accept(a); p++; } } }; //客户端 int main() { ObjectStructure * os= new ObjectStructure(); os->Add(new Man()); os->Add(new Woman()); Success* success = new Success(); os->Display(success); Failure* fl = new Failure(); os->Display(fl); return 0; }
相关文章推荐
- Java开发中的23种设计模式详解(3)行为型
- 设计模式之十一种行为型模式(附实例和详解)
- 详解java设计模式(三)之策略模式(行为型)
- Java经典设计模式之十一种行为型模式(附实例和详解)
- 详解java设计模式(四)之迭代器模式(行为型)
- 学习Java 23种设计模式详解笔记之行为型模式(三)
- Java经典设计模式之十一种行为型模式(附实例和详解)
- Java经典设计模式之十一种行为型模式(附实例和详解)
- Java开发中的23种设计模式详解_后续2_行为型模式
- 23种设计模式模式详解 Java 行为型模式(三)
- Java开发中的23种设计模式详解(3)行为型
- Java经典设计模式之十一种行为型模式(附实例和详解)
- Java经典设计模式之十一种行为型模式(附实例和详解)
- C#设计模式之行为型模式详解
- Java开发中的23种设计模式详解之三:11种行为型模式
- (转)Java经典设计模式(3):十一种行为型模式(附实例和详解)
- java中23种设计模式详解
- Java开发中的23种设计模式详解
- [导入]C#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式.zip(10.41 MB)
- Java研究之学习设计模式-简单工厂模式详解