设计模式之行为模式(全)

III 行为模式(11)

Template

Strategy

State

Observer

Memento

Mediator

Command

Visitor

Chain of Responsibility

Iterator

Interpreter

 

1,Template(模板模式)

这样的情况:某一算法在不同的模块中有不同的实现细节,这时,将算法框架放在一个抽象基类中,然后派生这个基类,各派生类根据各自的需要来实现算法细节.这就是Template模式.

Strategy模式解决的是和Template模式类似的问题,但是Strategy模式是将算法封装到一个类中,并采取组合的方式解决这个问题。

该模式的特点是高层(AbsCls)声明接口,底层(ConcreateCls)负责实现接口.高层再调用底层的实现, 但有一个缺陷: 如果另外还有一个算法,它声明在OtherAbsCls抽象类中,这时将OtherAbsCls与已有的AbsCls都作为ConcreateClsA,ConcreateClsB的基类,而在这两个子类中实现这两个算法,这时,再由AbsCls指针指向ConcreateCls对象,将无法调用OtherAbsCls中声明的算法,当然,OtherAbsCls指针指向ConcreateCls对象时也无法访问AbsCls中声明的算法.  这时,Strategy模式解决了这个问题.

 

class AbsCls

{

public:

    virtual void TemplateMethod()=0;  

protected:

    virtual void Op1()=0;

    virtual void Op2()=0;  //Op1,Op2构成算法TemplateMethod框架,放在抽象类AbsCls

};

 

class ConcreateCls_A:public AbsCls

{

public:

    void TemplateMethod(){   this->Op1();  this->Op2();  }//实现细节

protected:

    void Op1(){   cout<<"ConcreateCls_A::Op1/n";  }//原子实现

    void Op2(){   cout<<"ConcreateCls_A::Op2/n";  }

};

 

class ConcreateCls_B:public AbsCls

{

public:

    void TemplateMethod(){   this->Op1();  this->Op2();  }//实现细节

protected:

    void Op1(){   cout<<"ConcreateCls_B::Op1/n";  }

    void Op2(){   cout<<"ConcreateCls_B::Op2/n";  }

};

 

int main()

{

    AbsCls*pObjA=new ConcreateCls_A;

    pObjA->TemplateMethod();

 

    AbsCls*pObjB=new ConcreateCls_B;

    pObjB->TemplateMethod();

 

    return 0;

}

 

2, Strategy(策略模式).

上面说的Template模式的缺陷,这里用Strategy模式,采用组合的方式克服了这一缺陷. 下图中的Althrimlnterface是一个比上图中还要抽象的框架,可以理解为,除了表明它是算法之外,再无更具体的东西,不像上面的,知道它是算法,还知道它有Op1,Op2两个原子算法组成. ConcreateStra_A/B,实现的AlthrimInterface是彻头彻尾两个不同的算法, 也就是说,Strategy模式中,实现了多个算法.

class Strategy

{

public:

     virtual void AlgrithmInterface()=0;

};

 

class ConcreateStrategy_A:public Strategy

{

public:

     void AlgrithmInterface(){   cout<<"ConcreateStrategy_A::AlgrithmInterface/n";  }

};

 

class ConcreateStrategy_B:public Strategy

{

public:

     void AlgrithmInterface(){   cout<<"ConcreateStrategy_B::AlgrithmInterface/n";  }

};

 

class Context

{

public:

     Context(Strategy*pSt):_pSt(pSt){}

     void DoTheJob(){   _pSt->AlgrithmInterface();  }    //DoTheJob才是封装的算法框架

private:                                                     //其实现依赖于Stragegy子类的组合实现

     Strategy*_pSt;

};

 

int main()

{

     Strategy* pSt_A=new ConcreateStrategy_A;

     Context*  pCon_A=new Context(pSt_A);

     pCon_A->DoTheJob();

 

     Strategy* pSt_B=new ConcreateStrategy_B;

     Context* pCon_B=new Context(pSt_B);

     pCon_B->DoTheJob();

 

     return 0;

}

 

3,State (状态机模式)

State模式与Strategy模式有点相似,但它强调的是在不同状态下采取不同的动作”,如果不用State模式,则很可能会用到一组switch/case 语句,State克服了这一缺陷.克服的方法在下图中的那句注释中,下面的实现中只用了A,B两种状态,其实可有任意多种,添加ConcreateState_X就是了,然后在其Handle实现中,Context的状态改成你想要的状态即可.

State模式注重的是什么状态下采取什么动作, 如下面的 ConcreateState_A::Handle的实现可以看出,ConcreateState_A状态下,采取的动作将是打印出” ConcreateState_A::Handle”字串, 然后将状态改变为ConcreateState_B.

 

class Context;

class State       //状态类

{

public:

    virtual void Handle(Context*pCon)=0;//实际上用于改变Context的状态

};

 

class ConcreateState_A:public State

{

public:

    void Handle(Context*pCon);

};

 

class ConcreateState_B:public State

{

public:

    void Handle(Context*pCon);

 

};

 

class Context

{

public:

    State* GetState(){   return _pSt;  }//得到状态

    void SetState(State*pSt){   _pSt=pSt;  }//设置状态,实际上是将对象的指针SetState

    void Operation(){ _pSt->Handle(this);  }//操作,调用State的函数

private:

    State* _pSt;

};

 

void ConcreateState_A::Handle(Context*pCon)

{  

    cout<<"ConcreateState_A::Handle/n";    //具体操作

    if (pCon->GetState())       //如果当前状态指针不为NULL,则改变状态为B

    {

       pCon->SetState(NULL);

    }

    pCon->SetState(new ConcreateState_B);

}

void ConcreateState_B::Handle(Context*pCon)//具体操作

{  

    cout<<"ConcreateState_B::Handle/n";    //如果当前状态指针不为NULL,则改变状态为A

    if (pCon->GetState())

    {

       pCon->SetState(NULL);

    }

    pCon->SetState(new ConcreateState_A);

}

int main()

{

    State*pSt_A=new ConcreateState_A;

    Context* pCon=new Context;

    pCon->SetState(pSt_A); //一定要先设置一个状态再调用操作函数Operation

 

    pCon->Operation();  //实际上是 ConcreateState_AHandle函数在进行,且它把Context状态变为B

    pCon->Operation();  //实际上是 ConcreateState_AHandle函数在进行,且它把Context状态变为A

    pCon->Operation();

    pCon->Operation();

 

    return 0;

}

State模式问题主要是逻辑分散化,状态逻辑分布到了很多的State的子类中,很难看到整个的状态逻辑图,这也带来了代码的维护问题。

 

4,Observer (观测者模式)

对同一组数据进行统计分析时候,我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变。Observer模式就是解决了这一个问题。也就是说,观测者的任务是:当一多个事物依赖于一个事物时,这个事物变化的时候,那多个事物能随着变化.

上图中,attach,Detach用来注册/注销Observer对象到Subject对象中, 注册之后,如果Subject调用了SetState则说明Subject改变了,这时,它应该发送Notity消息, 则各个Observer对象都要进行相应的改变.

class Observer

{

public:

    virtual void Update()=0;

};

class Subject

{

public:

    virtual string GetState()=0;

    virtual void SetState(string sta)=0;

    virtual void Attach(Observer*pOb){     list_Ob.push_back(pOb);  }

    virtual void Detach(Observer*pOb){     list_Ob.remove(pOb); }

    virtual void Notify()       //Subject发出改变通知后,各个Observer自动更新

    {

       list<Observer*>::iterator it_Ob=list_Ob.begin();

 

       for (;it_Ob!=list_Ob.end();++it_Ob)(*it_Ob)->Update();//各个Observer自动更新

    }

private:

    list<Observer*>list_Ob;

};

 

class ConcreateSubject:public Subject

{

public: //注意,其他三个方法都没有重定义了.

    string GetState(){   return _state;    }

    void SetState(string sta){  _state=sta;/* Notify();*/   }//如果Notify()不注释掉

private:                                             //就能做到真正的Subject一变,

    string _state;                  //Observer立即跟着变,只是出于这样一种考虑:有时

};                                 //虽然Subject变化了,但却并不希望Observer改变

 

class ConcreateObserver_A:public Observer

{

public:

    ConcreateObserver_A(Subject*pSub){ _pSub=pSub;   }

    void Update(){    cout<<"Now the Subject state is: "<<_pSub->GetState()

                     <<" and I--ConcreateObserver_A-- am changing my state/n";   }   //观测者更新

private:

    Subject*_pSub;

};

 

class ConcreateObserver_B:public Observer

{

public:

    ConcreateObserver_B(Subject*pSub){ _pSub=pSub;   }

    void Update(){    cout<<"Now the Subject state is: "<<_pSub->GetState()

       <<" and I--ConcreateObserver_B-- am changing my state/n";   }   //观测者更新

private:

    Subject*_pSub;

};

 

int main()

{

    Subject*pSub=new ConcreateSubject;

   

    Observer*pOb_A=new ConcreateObserver_A(pSub);//由于这里用的是指针参数,所以尽管在

    Observer*pOb_B=new ConcreateObserver_B(pSub);//构造ConcreateObserver之前没有pSub->SetState

                                           //而在构造之后才SetState,结果也是一样的.

    pSub->Attach(pOb_A);//注册

    pSub->Attach(pOb_B);

 

    pSub->SetState("old");//状态设为old

    pSub->Notify(); //发出改变消息(状态是old),两个Observer都要改变

    pSub->SetState("new");//Subject的状态由old改变为new

    pSub->Notify();   //再次发出状态变化消息

 

    pSub->Detach(pOb_A); //注销

    pSub->Detach(pOb_B);

    return 0;

}

 

5,Memento(备忘录)

如操作系统的系统还原,可以通过Memento模式实现.另外如Undo,Redo也可以用Memento.这种模式常常需要大量的物理空间.

上图中,VC编程为例,调用Caretaker::SetMemento就设置了一个旧的状态,调用UnDo,就相当于按下了VC上那个弯键.state换成一个复杂的结构体,记录下很多信息,就能实现VCUNDO功能!

typedef string state;

class Memento  //备忘录

{

public:

    Memento(state sta){      mem_state=sta;    }

    state GetState(){ return mem_state; }

 

private:

    state mem_state; //备忘录保存的状态对象

};

 

class Originator  //老状态

{

public:

    //必须先SetStateCreateMemento

    void SetState(state sta){   ori_state=sta;       }

    state GetState(){ return ori_state; } //用于测试,可得知当前状态

 

    //生成一个备忘录对象,并将本身的状态对象传递/保存到备忘录中去.

    Memento* CreateMemento(){ pOriMem= new Memento(ori_state);  return pOriMem;   }

private:

    state ori_state; //软件主体(VC)的状态

 

    Memento* pOriMem;

};

 

class Caretaker  // 照看者,调用者

{

public:

    Caretaker(){  pCarMem=NULL; }

    void SetMemento(Memento* pMem){ pCarMem=pMem; }//这里的pMem通过OriginatorCreateMemento

                                               //函数来实例化.

    Memento*GetMemento(){    return pCarMem;   }

    state GetOldState(){ return GetMemento()->GetState();   }

    void UnDo(Originator * pOri ){    pOri ->SetState(GetOldState());  }

private:

   

    Memento* pCarMem;

};

 

int main()

{

    state Old="ON",New="OFF";

 

    Originator* pOri = new Originator;

    pOri->SetState(Old); //当前主体状态为Old

    cout<<"Current state of Originator is : "<<pOri->GetState()<<endl; //打印当前状态

 

    Caretaker* pCar = new Caretaker;

    pCar->SetMemento(pOri->CreateMemento());//一旦调用SetMemento就好比VC中按下"Undo"按钮

                     //,要先找到旧的状态,如果要保存多步状态,则这里可能不是Old作参数

 

    pOri->SetState(New); //主体已经进入一个新的状态New

    cout<<"Current state of Originator is : "<<pOri->GetState()<<endl; //打印新的当前状态

 

    cout<<"The old state of Memento is :"<<pCar->GetOldState()<<endl; //这里还可以获取旧的状态

    pCar->SetMemento(pOri->CreateMemento());//由于Originator只有一个State,

                                          //故本程序只能保存一步状态,可以扩展到多步.

    pCar->UnDo(pOri);//**********这才是目标!!*************

    cout<<"Current state of Originator is : "<<pOri->GetState()<<endl; //UnDo之后,恢复原来状态

 

   

    cout<<"The new state of Memento is :"<<pCar->GetOldState()<<endl; //备忘录中的新状态

    return 0;

}

6,Mediator(中介模式)

大型系统中的许多对象间的通信常常很复杂, 而如果使用Mediator模式, 专门建立一个类来维护对象间的通信,则可以使得各个对象间不必相互声明就能够通信,会大大地简化系统.

 

Mediator模式中,每个Colleague维护一个Mediator,当要进行交互,例如图中ConcreteColleagueAConcreteColleagueB之间的交互就可以通过ConcreteMediator提供的DoActionFromAtoB来处理,ConcreteColleagueAConcreteColleagueB不必维护对各自的引用,甚至它们也不知道各个的存在。Mediator通过这种方式将多对多的通信简化为了一(Mediator)对多(Colleague)的通信。

    class Mediator;

class Colleage

{

public:

    virtual void Communicate(Colleage*pC)=0;

    virtual void SayHello(string hello)=0; //奇怪,VC7下这里不用纯虚函数会报错,怪事.

protected:

    Colleage(Mediator*pMedia){  _pMedia=pMedia;   }

    Mediator*_pMedia;

};

 

class ConcreateColleage_A:public Colleage

{

public:

    void Communicate(Colleage*pB);  //尚未定义

 

    void SayHello(string hello){    cout<<"CC_A said: "<<hello<<endl;  }

    ConcreateColleage_A(Mediator*pMedia):Colleage(pMedia){  }

};

 

class ConcreateColleage_B:public Colleage

{

public:

    void Communicate(Colleage*pA);  //尚未定义

 

    void SayHello(string hello){    cout<<"CC_B said: "<<hello<<endl;  }

    ConcreateColleage_B(Mediator*pMedia):Colleage(pMedia){  }

};

 

class Mediator

{

public:

    virtual void DoActionA_2_B()=0;

    virtual void DoActionB_2_A()=0;

   

};

 

class ConcreateMediator:public Mediator

{

public:

    void IntroColleage(Colleage*pColA,Colleage*pColB) {  pCol_A=pColA; pCol_B=pColB; }

 

    void DoActionA_2_B(){    pCol_A->SayHello("This is A/n");   }

    void DoActionB_2_A(){    pCol_B->SayHello("This is B/n");   }

private:

    Colleage*pCol_A;

    Colleage*pCol_B;

};

//下面的函数中,参数pB的意义在于:当要通信的对象是pB,实际调用的正好是DoActionA_2_B.

//而是pA,调用的正好是DoActionB_2_A,如果还有其实的对象,则可照样扩展.

void ConcreateColleage_A::Communicate(Colleage*pB){  _pMedia->DoActionA_2_B();   }

void ConcreateColleage_B::Communicate(Colleage*pA){  _pMedia->DoActionB_2_A();   }

int main()

{

    ConcreateMediator*pM = new ConcreateMediator;

    Colleage*pA = new ConcreateColleage_A(pM);

    Colleage*pB = new ConcreateColleage_B(pM);

 

    pM->IntroColleage(pA,pB);

 

    pA->Communicate(pB); //ConcreateColleage_AConcreateColleage_B通信

    pB->Communicate(pA); //ConcreateColleage_BConcreateColleage_A通信

 

    return 0;

}

 

7, Command(命令)

Command模式通过将请求封装到一个对象(Command)中,并将请求的接受者存放到具体的ConcreteCommand类中(Receiver)中,从而实现调用操作的对象和操作的具体实现者之间的解耦。

class Reciever //命令接收者,其操作为Action

{

public:

    void Action(){    cout<<"I am the reciever, I got the command/n";  }

};

 

class Command //该类有一个Reciever*成员,可被继承,它有一个接口Excute,实际将调用Reciever::Action

{

public:

    virtual void Excute()=0;

    virtual void GetReciever(Reciever*pRecv)=0;

protected:

    Reciever*pRecv;

};

 

class ConcreateCommand:public Command

{

public:

    void GetReciever(Reciever*pRecv){  this->pRecv=pRecv;   } //找到命令接收者.

    void Excute(){    pRecv->Action();  }//Command接口Excute,实际将调用Reciever::Action

};

 

class Invoker //命令激活器

{

public:

    void SetCommand(Command*pCmd){  this->pCmd=pCmd;  }//设置命令

    void Invoke(){    pCmd->Excute();   } //激活!执行命令!

private:

    Command*pCmd;

};

 

int main()

{

    Reciever*pRecv=new Reciever;

    Command*pCmd=new ConcreateCommand;

    pCmd->GetReciever(pRecv);

 

    Invoker*pIk=new Invoker;

    pIk->SetCommand(pCmd);

    pIk->Invoke();

 

    return 0;

}

8,Vistor(访问者)

在面向对象系统的开发和设计过程,经常会遇到一种情况就是需求变更,因此不得不去修改已有的设计,最常见就是解决方案就是给已经设计、实现好的类添加新的方法去实现客户新的需求,这样就陷入了设计变更的梦魇:不停地打补丁,其带来的后果就是设计根本就不可能封闭、编译永远都是整个系统代码。

Visitor模式则提供了一种解决方案:将更新(变更)封装到一个类中(访问操作),并由待更改类提供一个接收接口,则可达到要求的效果。

上图中,vistor要对element做的处理可以vistconelement_A/B方法中进行.

class Element;

class ConElement_A;

class ConElement_B;

class Vistor

{

public:

    virtual void VistConElement_A(ConElement_A*pA)=0; //虽然本示例中这个指针参数没起到作用

    virtual void VistConElement_B(ConElement_B*pB)=0; //但实际用于设计时,肯定会有用的.

};

 

class ConVistor_A:public Vistor

{

public:

    void VistConElement_A(ConElement_A*pA){   cout<<"ConVistor_A will vist ConElement_A/n"; }

    void VistConElement_B(ConElement_B*pB){   cout<<"ConVistor_A will vist ConElement_B/n"; }

};

 

class ConVistor_B:public Vistor

{

public:

    void VistConElement_A(ConElement_A*pA){   cout<<"ConVistor_B will vist ConElement_A/n"; }

    void VistConElement_B(ConElement_B*pB){   cout<<"ConVistor_B will vist ConElement_B/n"; }

};

 

class Element

{

public:

    virtual void Accept(Vistor*pV)=0;

};

 

class ConElement_A:public Element

{

public:

    void Accept(Vistor*pV){  pV->VistConElement_A(this); }

    void Operation_B(){  }

};

 

class ConElement_B:public Element

{

public:

    void Accept(Vistor*pV){  pV->VistConElement_B(this); }

    void Operation_A(){  }

   

};

 

class Manger

{

public:

    void AttachElement(Element*pE){ list_Element.push_back(pE); }

    void DetachElement(Element*pE){ list_Element.remove(pE); }

 

    void AcceptVistor(Vistor*pV) //执行者

    {

       list_Vistor.push_back(pV);

       list<Element*>::iterator it_Element=list_Element.begin();

       for (;it_Element!=list_Element.end();++it_Element)(*it_Element)->Accept(pV);

    }

private:

    list<Vistor*>list_Vistor;

    list<Element*>list_Element;

};

/*

通过管理器Manger,Element在管理器中注册,一旦调用Manger::AcceptVistor(ConVistor_X)

则能够被Element对象AcceptConVistor_X的操作就会被执行.

*/

int main()

{

    Manger*pManger=new Manger;

 

    Element*pEA=new ConElement_A;

    Element*pEB=new ConElement_B;

 

    pManger->AttachElement(pEA); //注册

    pManger->AttachElement(pEB);

 

    Vistor*pVA=new ConVistor_A;

    Vistor*pVB=new ConVistor_B;

 

    pManger->AcceptVistor(pVA);//执行,实际上,pVAVistConElement_AVistConElement_A都将执行

    pManger->AcceptVistor(pVB);

 

    pManger->DetachElement(pEA);//注销

    pManger->DetachElement(pEB);

 

    return 0;

}

 

9, Chain of Responsibility(职责链)

MFC,消息会沿着固定的路径被传递,直到路径上某个对象将消息处理掉,如果半路上没被处理,则会被终极的App对象处理掉.

职责链模式就能够维护一条这样的路径”,它的做法是将可能会处理某些(或某个)请求的对象链接成一条链,然后把请求放到这条链上来传递,直到请求被处理.

详看注释.

class Handle

{

public:

    void SetHandle(Handle*pHan){    _pHan=pHan;   } //这是每个对象都要使用的方法,用来形成对象链

                                             //没有后续对象时,_pHan=NULL

    Handle*GetHandle(){  return _pHan; }   //获取后续对象

 

    virtual void ProcessRequest(int RequestID)=0;

protected:

    Handle*_pHan; //这是链中指针,指向下一个对象,注意其保护类型,可在派生时使用.

};

 

class ConCreateHandle_A:public Handle

{

public:

    void ProcessRequest(int RequestID) //每个ConCreateHandle_A对不同的ID的请求做不同的处理

    {     //在处理范围内

       if(RequestID<0)cout<<"I can process the Request which ID is: "<<RequestID<<endl;

       else if(GetHandle())//不在处理范围,但本对象还有后续对象

       {

           cout<<"My subsequencer will process the Request which ID is: "<<RequestID<<endl;

           GetHandle()->ProcessRequest(RequestID);

       }//不在处理范围,而且本对象没有后续对象了.

       else cout<<"One body can process the Request which ID is: "<<RequestID<<endl;

    }

};

 

class ConCreateHandle_B:public Handle

{

public:

    void ProcessRequest(int RequestID)

    {//上面只能处理ID小于0的请求,这里能处理ID小于100.

       if(RequestID<100)cout<<"I can process the Request which ID is: "<<RequestID<<endl;

       else if(GetHandle())

       {

           cout<<"My subsequencer will process the Request which ID is: "<<RequestID<<endl;

           GetHandle()->ProcessRequest(RequestID);

       }

       else cout<<"One body can process the Request which ID is: "<<RequestID<<endl;

    }

};

 

int main()

{

    Handle*pHA=new ConCreateHandle_A;

    Handle*pHB=new ConCreateHandle_B;

    pHA->SetHandle(pHB);//本例中SetHandle是每个对象必须调用的.

    pHB->SetHandle(NULL);

   

    int RequestID=200;

    pHA->ProcessRequest(RequestID); //让一个ID200的请求在链上传递

 

    return 0;

}

 

10,Iterator(迭代器)

这个模式可以参考STL中迭代器的意义来理解,STL中的迭代器通过一个类似指针的模板类实现对list,string等聚合对象的遍历.

Iterator模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个类中进行,这样就避免了暴露这个聚合对象的内部表示的可能

代码:

class Iterator;

class List_It;

class Vector_It;

class Container

{

public:

//  Container(){  ++size; pNextCon=NULL;   }//用一个表态变量size来标记容器大小,构造一次自增一回

    virtual Iterator*CreaeteIterator()=0;

    void Add(Container*pNextCon){   this->pNextCon=pNextCon; }   //往容器中聚合更多对象  

    Container*GetNextContainer(){   return pNextCon;  } //下一个结点

              /*其他方法略*/

protected:

    Container*pNextCon;

};

 

class List:public Container //容器List

{

public:

    List(){    ++size;    }

    Iterator*CreaeteIterator();

    int GetSize(){    return size;  }   //得到窗口大小

private:

    static int size;

};

int List::size=0;

class Vector:public Container //容器Vector

{

public:

    Vector(){  ++size;    }

    Iterator*CreaeteIterator();

    int GetSize(){    return size;  }   //得到窗口大小

private:

    static int size;

};

int Vector::size=0;

 

class Iterator    //迭代器

{

public:

    virtual Container* First()=0;//第一个位置

    virtual Container* Next()=0; //下一个位置

    virtual int GetSize()=0;     //容器大小

};

 

class List_It:public Iterator

{

public:

    List_It(List*pList){ this->pList=pList;   } //以对应的容器指针为参数构造迭代器

    List*GetList(){      return pList; }

    Container*First(){   return pList; }   //这里粗制滥造了,主要用于模拟

    Container*Next(){ return GetList()->GetNextContainer();  }

    int GetSize(){    return pList->GetSize(); }

private:             //迭代器必须有一个与之对应的容器指针

    List*pList;

};

 

class Vector_It:public Iterator

{

public:

    Vector_It(Vector*pVector){  this->pVector=pVector;   }

    Vector* GetVector()  {   return pVector;   }

    Container*First(){   return pVector;   }

    Container*Next(){ return GetVector()->GetNextContainer();   }

    int GetSize(){    return pVector->GetSize();  }

private:

    Vector*pVector;

};

Iterator* List::CreaeteIterator(){ return new List_It(this);   } //List构造自己的迭代器

Iterator* Vector::CreaeteIterator(){   return new Vector_It(this); }//Vector构造自己的迭代器

int main()

{

    List*pLA=new List;

    List*pLB=new List;

    List*pLC=new List;

 

    pLA->Add(pLB);//组成一个有三个List对象的链

    pLB->Add(pLC);

    pLC->Add(NULL);

 

    Iterator*pLIt=pLA->CreaeteIterator();//构造一个List_It 迭代器

 

    int list_size=pLIt->GetSize();  //用迭代器来获取容器的大小

 

    cout<<"The size of the Chain of List-Objs is: "<<list_size<<endl;//3

 

    Vector*pVA=new Vector;

    Vector*pVB=new Vector;

    Vector*pVC=new Vector;

    Vector*pVD=new Vector;

 

    pVA->Add(pVB);

    pVB->Add(pVC);

    pVC->Add(pVD);

    pVD->Add(NULL);

 

    Iterator*pVIt=pVA->CreaeteIterator();

    int vector_size=pVIt->GetSize();

    cout<<"The size of the Chain of Vector-Objs is: "<<vector_size<<endl;//4

 

    return 0;

}

 

11, Interpreter(解释器)

Interpreter模式能够为一门语言定义一个解释器,通过这个解释器可能解释该门语言的句子.

如果某种类型的问题发生的频率非常高,就值得为该类型问题的各个实例定义一个句子,并实现该句子的一个解释器,从此以后,解决该类型的问题就不会很费事了.

class ExpressionContext

{

public:

    ExpressionContext(string context){ this->context=context;   }

    string GetContext(){ return context;   }

private:

    string context;

};

 

class Expression

{

public://解释语句,不同的语句由不同的派生类解释

    virtual void Interpre(ExpressionContext*pContext)=0;

};

 

class TerminalExpression:public Expression

{

public:

    void Interpre(ExpressionContext*pContext) //一种解释

    {   cout<<"TermianlExpression--"<<pContext->GetContext()<<endl; }

};

 

class NonterminalExpression:public Expression

{

public:

    void Interpre(ExpressionContext*pContext)//又一种解释

       {   cout<<"NonermianlExpression--"<<pContext->GetContext()<<endl;  }

};

 

int main()

{

    ExpressionContext*pContext1=new ExpressionContext("hello world");

    ExpressionContext*pContext2=new ExpressionContext("HELLO WORLD");

 

    Expression*pExTer=new TerminalExpression;

    pExTer->Interpre(pContext1); //小写的解释

 

    Expression*pExNonter=new NonterminalExpression;

    pExNonter->Interpre(pContext2);//大写的解释

 

    return 0;

}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值