设计模式

单件模式要点,C++实现时需要注意拷贝构造函数和赋值运算符只申明不实现,这样的目的是为了阻止默认的拷贝构造函数和赋值运算。实现有延迟式和饥饿式。延迟式需要设置一个类似计数器的东西。饥饿式就直接在构造的时候实现即可。

这种实际在main函数中创建会报错,不明白为何, 而且还存在一个问题就是最后内存没有释放

#include<iostream>
using namespace std;

class LogManager{
private:
   static LogManager* instance;
   LogManager() {
      cout<<"构造函数"<<endl;
   }
   ~LogManager() {
      cout<<"析构函数"<<endl;
   }
   LogManager(const LogManager&);
   LogManager& operator=(const LogManager&);
public:
    static LogManager*  GetInstance() {
       if(LogManager::instance == NULL) {
         LogManager::instance = new LogManager();
       }
       return LogManager::instance;
    }
};

int main() {
   //LogManager *lm = LogManager::GetInstance();
  // LogManager *lm1 = LogManager::GetInstance();
  // delete lm;
  // delete lm1;
}
换了一种思路,内存释放的问题也解决了

#include<iostream>
using namespace std;

class LogManager{
private:

   LogManager() {
      cout<<"构造函数"<<endl;
   }
   ~LogManager() {
      cout<<"析构函数"<<endl;
   }
   LogManager(const LogManager&);
   LogManager& operator=(const LogManager&);
public:
    static LogManager*  GetInstance() {
       static LogManager instance;
       return &instance;
    }
};

int main() {
   LogManager *lm = LogManager::GetInstance();
   LogManager *lm1 = LogManager::GetInstance();
  // delete lm;
  // delete lm1;
}

工厂模式要点,定义一个创建产品的接口(顶层工厂类),而由该接口的子类(具体工厂类),决定具体实例化哪种产品。创建产品的工厂树与原来产品树同构

简单工厂方法要点,就是工厂方法中没有必要派生那么多工厂类,可以采取的办法有三种

1.       将多个方法放到同一个工厂类里面

2.       构造不同的参数列表,利用重载

3.       直接将工厂类退化到产品类中

原型方法要点,实际上就是首先创建一个抽象类申明clone接口,由参与原型设计的所有子类需实现clone方法,具体就是做拷贝构造函数,实现的时候,需要有一个原型管理器,管理的方法有两种,一种是设定id,登记式,另一种是保持一个可用的原型注册表。

构造器模式要点,将一个复杂对象的创建与它的表示分离,使得同样的创建过程可以创建不同的表示。

抽象工厂模式要点,实际就是有多个产品树,然后将与不同产品树同构的工厂树融合到一颗树里面,称之为抽象工厂


桥接模式要点,主要目的是将单个方向的变化分离开,两个方向同时变化采取的步骤是,第一步,将接口和实现分离,第二步,使用组合的方式连接接口和实现,第三步,接口和实现的独立变化。


/*现Mouse类的定义如下:
class Mouse
{
public:
    void Walk( int steps )
        { cout<<"Implement for Walk() with Verson 1."}
    void AddMoney(int m)
        { cout<<"Implement for AddMoney() with Verson 1."}
private:
    int  posX;
    int  posY;
};
  
   若已知:在后续的版本中,如version2中,
   a)可能会增加Mouse类的行为,如增加Drive(int steps)和Fly(int steps);
   b)可能需要改变Walk(int steps)的具体实现细节;
   c)可能会增加其它数据成员,如将2D位置信息改为3D位置信息等。
   d)希望在新版本中,尽可能地通过扩展老版本,适应新需求。

   请使用桥接模式重新设计Mouse类及相关类。*/
#include<iostream>
using namespace std;

class AbstractMouse{
public:
   AbstractMouse();
   virtual ~AbstractMouse();
   virtual void Walk(int steps);
   virtual void AddMoney(int m);
};

class ImpMouse{
public:
   ImpMouse() {}
   virtual ~ImpMouse() {}
   virtual void Walk(int steps) {
      cout<<"Implement for Walk() with Verson 1."<<endl;
   }
   virtual void AddMoney(int m) {
      cout<<"Implement for AddMoney() with Verson 1."<<endl;
   }
protected:
   int posX;
   int posY;
};

class Mouse{
public:
   Mouse(ImpMouse *imouse):im(imouse){}
   virtual ~Mouse(){
      delete im;
   }
   virtual void Walk(int steps) {
      im->Walk(steps);
   }
   virtual void AddMoney(int m) {
      im->AddMoney(m);
   }
private:
   ImpMouse *im;
};

class ImpMouse1:public ImpMouse{
public:
   virtual void Walk(int steps) {
      cout<<"New implement for Walk() with Version 2."<<endl;
   }
protected:
   int posY;
};

class NewMouse:public Mouse{
public:
   NewMouse(ImpMouse *imouse):Mouse(imouse) {}
   virtual void Drive(int steps) {
      cout<<"Implement for Drive() with Version 2."<<endl;
   }
   virtual void Fly(int steps) {
      cout<<"Implement for Fly() with Version 2."<<endl;
   }
};

int main() {
   ImpMouse *im = new ImpMouse1();
   NewMouse *mouse = new NewMouse(im);
   mouse->Walk(1);
   mouse->AddMoney(5);
   mouse->Drive(4);
   mouse->Fly(6);
   return 0;
}


适配器模式要点, 分为类适配器和对象适配器,所谓类适配器,就是利用多重继承来实现,适配器类多重继承主动适配的类,和被动适配的类,而对象适配器就是,将被动适配的类的对象实例放在适配器中,成为适配器的私有成员。

 

/*已知Map类的实现如下,其中Draw()的实现使用DirectX10绘制。
class Map
{
public:
    void Draw()
    { cout<<"Draw Map with DirectX10."}
    //...
private:
    //...
};

  现需要将Map类移植到多种平台上,由于DirectX局限性,需要用OpenGL,而不是DX10。

  现决定利用第三方的OpenGL相关类库实现上述需求。其中OpenGL库中的相关类如下:
class Graph
{
public:
    virtual ~Graph() {}
    virtual void OGL_Draw() const = 0;
};

class WinGraph:public Graph
{
public:
    virtual ~WinGraph() {}
    virtual void OGL_Draw() const
    { cout<< "Draw with OpenGL on Windows. "<<endl;}
};

class UnixGraph:public Graph
{
public:
    virtual ~UnixGraph() {}
    virtual void OGL_Draw() const
    { cout<< "Draw with OpenGL on Unix. "<<endl;}
};

    问题:请使用对象适配器模式,在不改变Map类接口的条件下,完成相关类的设计。


*/
#include<iostream>
using namespace std;

class Graph{
public:
   virtual ~Graph() {}
   virtual void OGL_Draw() const = 0;
};

class WinGraph:public Graph{
public:
   virtual ~WinGraph() {}
   virtual void OGL_Draw() const {
      cout<<"Draw with OpenGL on Windows. "<<endl;
   }
};

class UnixGraph:public Graph{
public:
   virtual ~UnixGraph() {}
   virtual void OGL_Draw() const {
      cout<<"Draw with OpenGL on Unix. "<<endl;
   }
};

class Map{
public:
   virtual void Draw() {
      cout<<"Draw Map with DirectX10. "<<endl;
   }
private:

};

class Adapter:public Map{
public:
   Adapter(Graph* g):graph(g) {}
   virtual ~Adapter() {
      delete graph;
   }
   virtual void Draw() {
      graph->OGL_Draw();
   }
private:
   Graph *graph;
};

int main() {
   Graph *grf = new WinGraph();
   Map *mp = new Adapter(grf);
   mp->Draw();
   delete mp;
   delete grf;
   return 0;
}

合成模式要点,分为透明式的合成和安全式的透明模式,主要区别就是Add,Remove,GetChild这些操作不在抽象类中申明,就是安全的,申明就是透明的。主要就是使用继承,然后使用它们公有的基类的vector来进行统一处理,使用到多态机制,然后就是使用vector时,删除元素的操作为(需要添加头文件,<vector>,<algorithm>,find是algorithm这个头文件中的函数)vectorName.erase(find(vectorName.begin().vectorName.end(),  item));

 

/*   一副地图,由多条Road组成,每条Road由多个Block组成,每个Block又包含多个Building。

   现希望:
   1.地图中的各种组成元素,具有一致的访问方法;
   2.不同场景地图中,各元素可能会有不同的组成形式或结构。

  问题:请使用合成模式,设计相关类。

*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class AbstractMap{
public:
   AbstractMap() {}
   virtual ~AbstractMap() {}
   virtual void show() = 0;
   virtual void AddChild(AbstractMap* ) = 0;
   virtual void RemoveChild(AbstractMap* ) = 0;
};

class Building:public AbstractMap{
public:
   Building(int ID):id(ID) {}
   virtual ~Building() {}
   virtual void show() {
      cout<<"        Building "<<id<<endl;
   }
   virtual void AddChild(AbstractMap* ) {}
   virtual void RemoveChild(AbstractMap*) {}
private:
   int id;
};

class Block:public AbstractMap{
public:
   Block(int ID):id(ID) {}
   virtual ~Block() {
      myblock.empty();
   }
   virtual void show() {
      cout<<"     Block "<<id<<" it contains these building:"<<endl;
      for(vector<AbstractMap*>::iterator it = myblock.begin(); it!=myblock.end(); ++it) {
         (*it)->show();
      }
      cout<<"     end of block "<<id<<endl;
   }
   virtual void AddChild(AbstractMap* am) {
      myblock.push_back(am);
   }
   virtual void RemoveChild(AbstractMap* am) {
      myblock.erase(find(myblock.begin(), myblock.end(), am));
   }
private:
   vector<AbstractMap *> myblock;
   int id;
};

class Road:public AbstractMap{
public:
   Road(int ID):id(ID) {}
   virtual ~Road() {
      myroad.empty();
   }
   virtual void show() {
      cout<<"  Road "<<id<<" it contains these Blocks:"<<endl;
      for(vector<AbstractMap*>::iterator it = myroad.begin(); it!=myroad.end(); ++it) {
         (*it)->show();
      }
      cout<<"  end of road "<<id<<endl;
   }
   virtual void AddChild(AbstractMap* am) {
      myroad.push_back(am);
   }
   virtual void RemoveChild(AbstractMap* am) {
      myroad.erase(find(myroad.begin(), myroad.end(), am));
   }
private:
   vector<AbstractMap*> myroad;
   int id;
};

class Map:public AbstractMap{
public:
   Map(int ID):id(ID) {}
   virtual ~Map() {
      mymap.empty();
   }
   virtual void show() {
      cout<<"Map "<<id<<" it contains these Roads:"<<endl;
      for(vector<AbstractMap*>::iterator it = mymap.begin(); it!=mymap.end(); ++it) {
         (*it)->show();
      }
      cout<<"end of map "<<id<<endl;
   }
   virtual void AddChild(AbstractMap* am) {
      mymap.push_back(am);
   }
   virtual void RemoveChild(AbstractMap* am) {
      mymap.erase(find(mymap.begin(), mymap.end(), am));
   }
private:
   vector<AbstractMap*> mymap;
   int id;
};

int main() {
   Building *bu1 = new Building(1);
   Building *bu2 = new Building(2);
   Building *bu3 = new Building(3);
   Building *bu4 = new Building(4);
   Building *bu5 = new Building(5);
   Block *bl1 = new Block(1);
   bl1->AddChild(bu1);
   bl1->AddChild(bu2);
   bl1->AddChild(bu3);
   Block *bl2 = new Block(2);
   bl2->AddChild(bu4);
   Block *bl3 = new Block(3);
   bl3->AddChild(bu5);
   Road *ro1 = new Road(1);
   ro1->AddChild(bl1);
   ro1->AddChild(bl2);
   Road *ro2 = new Road(2);
   ro2->AddChild(bl3);
   Map *ma = new Map(1);
   ma->AddChild(ro1);
   ma->AddChild(ro2);
   ma->show();
   cout<<"------------------改变组成结构---------------"<<endl;
   bl1->RemoveChild(bu3);
   bl1->RemoveChild(bu2);
   bl2->AddChild(bu3);
   bl3->AddChild(bu2);
   ma->show();
   return 0;
}

门面模式要点,是为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

 

装饰模式要点

/*class Mouse
{
public:
    virtual ~Mouse() { }
    virtual void Walk( int steps )=0;
};

class RichMouse:public Mouse
{
public:
    virtual ~RichMouse() { }
    virtual void Walk( int steps )
        {  cout<<" RichMouse::Walk(); "; }
};

class PoorMouse:public Mouse
{
public:
    virtual ~PoorMouse() { }
    virtual void Walk( int steps )
        {  cout<<" PoorMouse::Walk(); "; }
};

现希望
  1. 给各Mouse类扩充一些功能,如在RichMouse类的Walk行为之前,增加损失10%金钱的功能;
     而在PoorMouse类的Walk行为之前,增加提高5%幸运值的功能,在walk之后,增加等待1回合的功能等;
  2. 功能的改变,只能是在原有行为功能的基础上的进一步扩充。当然,不同的类可以有不同的功能扩充;
  3. 功能的扩充会是经常性的,而且按哪个方向扩充,扩充什么,怎么扩充等问题,目前难以确定。

  问题:请使用装饰模式设计Mouse类及相关类,使它们能够适应上述需要。

*/
#include<iostream>
using namespace std;

class Mouse{
public:
   virtual ~Mouse() {}
   virtual void Walk(int steps) = 0;
};

class RichMouse:public Mouse{
public:
   virtual ~RichMouse() {}
   virtual void Walk(int steps) {
      cout<<"RichMouse::Walk();"<<endl;
   }
};

class PoorMouse:public Mouse{
public:
   virtual ~PoorMouse() {}
   virtual void Walk(int steps) {
      cout<<"PoorMouse::Walk();"<<endl;
   }
};

class Decorator:public Mouse{
protected:
   Mouse* mouse;
public:
   Decorator(Mouse* m):mouse(m) {}
   virtual ~Decorator() {
      delete mouse;
   }
   virtual void Walk(int steps) {
      mouse->Walk(steps);
   }
};

class LessenMoney:public Decorator{
private:
   double money;
public:
   LessenMoney(Mouse* m):Decorator(m) {
      money = 1000;
   }
   virtual ~LessenMoney() {}
   void lessen() {
      money = money*0.9;
      cout<<"RichMouse::lessen()."<<endl;
   }
   virtual void Walk(int steps) {
      lessen();
      Decorator::Walk(5);
   }
};

class AddValue:public Decorator{
private:
   double luckvalue;
public:
   AddValue(Mouse* m):Decorator(m) {
      luckvalue = 100;
   }
   virtual ~AddValue() {}
   void addvalue() {
      luckvalue = luckvalue*1.05;
      cout<<"PoorMouse::addvalue()."<<endl;
   }

   virtual void Walk(int steps) {
      addvalue();
      Decorator::Walk(5);
   }
};

class WaitFor:public Decorator{
public:
   WaitFor(Mouse* m):Decorator(m) {}
   virtual ~WaitFor() {}
   void wait() {
      cout<<"WaitFor::wait()."<<endl;
   }
   virtual void Walk(int steps) {
      Decorator::Walk(5);
      wait();
   }
};

int main() {
   Mouse* rm = new RichMouse();
   Mouse* lm = new LessenMoney(rm);
   lm->Walk(5);
   cout<<endl;
   Mouse* pm = new PoorMouse();
   Mouse* av = new AddValue(pm);
   Mouse* wf = new WaitFor(av);
   wf->Walk(5);
   cout<<endl;
   /*
   cout<<"------------动态撤销部分功能------------------"<<endl;
   pm->Walk(5);
   Mouse* m(av);
   m->Walk(5);*/
   return 0;
}



在以下情况下应当使用装饰模式:

1.需要扩展一个类的功能,或给一个类增加附加责任。 

2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。 

3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

与适配器模式的区别:

1.关于新职责:适配器也可以在转换时增加新的职责,但主要目的不在此。装饰者模式主要是给被装饰者增加新职责的。

2.关于原接口:适配器模式是用新接口来调用原接口,原接口对新系统是不可见或者说不可用的。装饰者模式原封不动的使用原接口,系统对装饰的对象也通过原接口来完成使用。(增加新接口的装饰者模式可以认为是其变种--“半透明”装饰者)

3.关于其包裹的对象:适配器是知道被适配者的详细情况的(就是那个类或那个接口)。装饰者只知道其接口是什么,至于其具体类型(是基类还是其他派生类)只有在运行期间才知道。

 

代理模式要点


与其他模式的区别

1)适配器模式Adapter

适配器Adapter为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,因此,它的接口实际上可能只是实体接口的一个子集。

2)装饰器模式Decorator

尽管Decorator的实现部分与代理相似,但Decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。

 

享元模式要点,享元对象能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态是存储在享元对象内部并且不会随环境改变而改变。因此内蕴状态并可以共享。

外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态与内蕴状态是相互独立的。图跟原型模式一样

 

策略模式要点, 实际就是将算法抽象为一个类,一种实现就是其的一个子类,通过多态运行时绑定来确定

和其他设计模式的区别:

1,与状态模式

在解决的问题上,状态模式是解决内在状态的改变,而策略模式是解决内部算法的改变。在解决的方法上,状态模式是自我控制状态的改变,而策略模式是由外部制定使用啥策略。

2,简单工厂模式

简单工厂模式是创建型模式,关注对象的创建。策略模式是行为型模式,关注行为的封装。简单工厂模式是根据不同的条件返回一个适合的类给你使用,然后调用者使用工厂类返回的类去完成相应的操作。而策略模式是必须首先创建一个想使用的类实例,然后实例被当作参数传递进去,既而通过该实例去调用不用的算法。在简单工厂模式中实现了通过条件选取一个类去实例化对象,策略模式则将选取相应对象的工作交给模式的使用者,它本身不去做选取工作。

 

状态模式要点,实际就是把状态抽象出来,然后每一种状态的操作都设计为一个子类,最后在拥有这些状态变化的主题中,设计一个抽象类的指针,也是通过多态来实现。

#include<iostream>
using namespace std;

class Tank;

class State{
public:
   virtual ~State() {}
   virtual void move(int x, int y) = 0;
   virtual void attack() = 0;
};

class StateA:public State{
public:
   StateA(Tank *t):tank(t) {}
   virtual ~StateA() {}
   virtual void move(int x, int y) {
      cout<<"in AtateA, can't move"<<endl;
   }
   virtual void attack() {
      cout<<"attack power is 40"<<endl;
   }
private:
   Tank* tank;
};

class StateB:public State{
public:
   StateB(Tank* t):tank(t) {}
   virtual ~StateB() {}
   virtual void move(int x, int y) {
      cout<<"move to ("<<x<<", "<<y<<")"<<endl;
   }
   virtual void attack() {
      cout<<"attack power is 20"<<endl;
   }
private:
   Tank* tank;
};

class Tank{
public:
   Tank() {
      statea = new StateA(this);
      stateb = new StateB(this);
      state = statea;
   }
   virtual ~Tank() {
      delete state;
      delete statea;
      delete stateb;
   }
   void attack() {
      state->attack();
   }
   void move(int x, int y) {
      state->move(x, y);
   }
   void setmode(State* sta) {
      state = sta;
   }
private:
   State* state;
   StateA* statea;
   StateB* stateb;
};

int main() {
   Tank tank;
   State *stab = new StateB(&tank);
   tank.attack();
   tank.move(1, 4);
   tank.setmode(stab);
   tank.attack();
   tank.move(2, 7);
   return 0;
}



中介者模式要点,实际就是类不直接进行交互,然后定义一个中介者来根据不同的条件来为他们进行交互,没有用到多态

#include<iostream>
#include<string>
using namespace std;

class Mediator;

class Person{
public:
   virtual ~Person() { }
   virtual void SendMessage(string message) = 0;
   virtual void GetMessage(string message) = 0;
   virtual void SetMediator(Mediator* mediator) {
      m_mediator = mediator;
   }
protected:
   Mediator* m_mediator;
};

class Mediator{
public:
   virtual void Send(string Message, Person* person) = 0;
   virtual void SetA(Person* A) = 0;
   virtual void SetB(Person* B) = 0;
};

class Renter:public Person{
public:
   virtual ~Renter() {}
   virtual void SendMessage(string message) {
      m_mediator->Send(message, this);
   }
   virtual void GetMessage(string message) {
      cout<<"renter recved "<<message<<endl;
   }
};

class Landlord:public Person{
public:
   virtual ~Landlord() {}
   virtual void SendMessage(string message) {
      m_mediator->Send(message, this);
   }
   virtual void GetMessage(string message) {
      cout<<"landlord recved "<<message<<endl;
   }
};

class HouseMediator:public Mediator{
public:
   virtual ~HouseMediator() {}
   virtual void SetA(Person* A) {
      m_a = A;
   }
   virtual void SetB(Person* B) {
      m_b = B;
   }
   virtual void Send(string message, Person *person) {
      if(person == m_a) {
         m_b->GetMessage(message);
      } else {
         m_a->GetMessage(message);
      }
   }
private:
   Person *m_a;
   Person *m_b;
};

int main() {
   HouseMediator *hm = new HouseMediator();
   Person *r = new Renter();
   Person *l = new Landlord();
   hm->SetA(r);
   hm->SetB(l);
   r->SetMediator(hm);
   l->SetMediator(hm);
   r->SendMessage("I want to rent a house");
   l->SendMessage("I have a house to rent out");
   delete r;
   delete l;
   delete hm;
   return 0;
}



观察者模式要点,实际就是类似注册的,观察者的具体的类,在构造时,在自己感兴趣的主题类上注册自己感兴趣的事,析构时注销,然后该主题对象定义一个Notify操作,用于将状态的改变告知所有对自己感兴趣的的观察者的具体的类。用到vector

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

class Observer{
public:
   virtual ~Observer() {}
   virtual void Update() = 0;
};

class Subject{
public:
   Subject() {}
   virtual ~Subject() {}
   virtual void Attach(Observer *obj) {
      observers.push_back(obj);
   }
   virtual void Detach(Observer *obj) {
      observers.erase(find(observers.begin(), observers.end(), obj));
   }
   virtual void Notify() {
      for(vector<Observer*>::iterator it = observers.begin(); it != observers.end(); ++it) {
            (*it)->Update();
      }
   }
private:
   vector<Observer *>observers;
};



class ClockTimer:public Subject{
public:
   virtual ~ClockTimer() {}
   virtual int GetHour() {
      return 9;
   }
   virtual int GetMinute() {
      return 10;
   }
   virtual int GetSecond() {
      return 57;
   }
   void Tick() {
      Notify();
   }
};

class DigitalClock:public Observer{
public:
   DigitalClock(ClockTimer *ct):clocktime(ct) {
      clocktime->Attach(this);
   }
   virtual ~DigitalClock() {
      clocktime->Detach(this);
   }
   virtual void Update() {
      Draw();
   }
   void Draw() {
      int h = clocktime->GetHour();
      int m = clocktime->GetMinute();
      int s = clocktime->GetSecond();
      cout<<"the current time is "<<h<<" "<<m<<" "<<s<<endl;
   }
private:
   ClockTimer *clocktime;
};

class AnalogClock:public Observer{
public:
   AnalogClock(ClockTimer *ct):clocktime(ct) {
      clocktime->Attach(this);
   }
   virtual ~AnalogClock() {
      clocktime->Detach(this);
   }
   virtual void Update() {
      Draw();
   }
   void Draw() {
      int h = clocktime->GetHour();
      int m = clocktime->GetMinute();
      int s = clocktime->GetSecond();
      cout<<"the current time is "<<h<<"µã"<<m<<"·Ö"<<s<<"Ãë"<<endl;
   }
private:
   ClockTimer *clocktime;
};

int main() {
   ClockTimer *ct = new ClockTimer();
   DigitalClock *dc = new DigitalClock(ct);
   AnalogClock *ac = new AnalogClock(ct);
   ct->Notify();
   delete dc;
   delete ac;
   return 0;
}



命令模式要点,将行为的请求者和行为的实现者分离,行为的实现者是Requester,行为的请求者是ConcreteCommand,每个请求者内都有一个指向实现者的指针,然后根据需要调用实现者内不同的方法,此外还有一个聚合所有命令的类,作用类似于服务员。

 

#include<iostream>
using namespace std;

class Command{
public:
   virtual void Excute() = 0;
};

class Requester{
public:
   virtual void DoAction(Command *comm) {
      comm->Excute();
   }
};

class Receiver{
public:
   void DoSomething1() {
      cout<<"DoSomething1"<<endl;
   }
   void DoSomething2() {
      cout<<"DoSomething2"<<endl;
   }
};

class CommandAction1:public Command{
public:
   CommandAction1(Receiver *rec):recv(rec) {}
   virtual void Excute() {
      recv->DoSomething1();
   }
private:
   Receiver *recv;
};

class CommandAction2:public Command{
public:
   CommandAction2(Receiver *rec):recv(rec) {}
   virtual void Excute() {
      recv->DoSomething2();
   }
private:
   Receiver *recv;
};

class MacroCommand:public Command{
public:
   MacroCommand(Command *cm1, Command *cm2):cmd1(cm1), cmd2(cm2) {}
   virtual ~MacroCommand() {}
   virtual void Excute() {
      cmd1->Excute();
      cmd2->Excute();
   }
private:
   Command *cmd1;
   Command *cmd2;
};

int main() {
   Receiver *recv = new Receiver();
   Command *cmd1 = new CommandAction1(recv);
   Command *cmd2 = new CommandAction2(recv);
   MacroCommand *mc = new MacroCommand(cmd1, cmd2);
   mc->Excute();
   delete mc;
   delete cmd1;
   delete cmd2;
   delete recv;
   return 0;
}

模板方法模式要点,STL 中的sort,find函数都是模板方法。

 

访问者模式要点,主要解决一个类层次树结构稳定的前提下,处于另一个类层次结构中的类需要对稳定的那个类结构层次进行访问。然后变化的部分采用重载,不变的部分采用多态。

决定执行哪个具体行为过程,由消息名,接收对象,参数共同决定。

除消息名之外,

若由接收对象决定行为过程,称单分派; (动态单分派,多态)

若由接收对象和参数对象共同决定行为过程,称多分派;(静态多分派,重载)


#include<iostream>
#include<list>
using namespace std;

class Element;

class Visitor{
public:
   virtual ~Visitor() {}
   virtual void visit(Element *ele) = 0;
};

class Element{
public:
   virtual ~Element() {}
   virtual void Accept(Visitor *vis) = 0;
};

class Employee:public Element{
public:
   string name;
   double income;
   int vocationDays;
public:
   Employee(string nm, double ic, int vd):name(nm), income(ic), vocationDays(vd) {}
   virtual ~Employee() {}
   virtual void Accept(Visitor *vis) {
      vis->visit(this);
   }
};

class IncomeVisitor:public Visitor{
public:
   virtual void visit(Element *ele) {
      Employee *emp = ((Employee*)ele);
      emp->income += 1000;
      cout<<emp->name<<" new income "<<emp->income<<endl;
   }
};

class VocationVisitor:public Visitor{
public:
   virtual void visit(Element *ele) {
      Employee *emp = ((Employee*)ele);
      emp->vocationDays += 1;
      cout<<emp->name<<" new vocationDays "<<emp->vocationDays<<endl;
   }
};

class Employees{
private:
   list<Employee*> emp;
public:
   void Attach(Employee* ele) {
      emp.push_back(ele);
   }
   void Detach(Employee* ele) {
      emp.remove(ele);
   }
   void Accept(Visitor *vis) {
      for(list<Employee*>::iterator it = emp.begin(); it != emp.end(); ++ it) {
         (*it)->Accept(vis);
      }
   }
};

int main() {
   Employees *e = new Employees();
   e->Attach(new Employee("Tom", 25000, 14));
   e->Attach(new Employee("Tomas", 35000, 16));
   e->Attach(new Employee("Roy", 45000, 21));
   IncomeVisitor *v1 = new IncomeVisitor();
   VocationVisitor *v2 = new VocationVisitor();
   e->Accept( v1 );
   e->Accept( v2 );
   delete e;
   return 0;
}

#include<iostream>
using namespace std;

/*Tiger->Cook()
  Tiger->Eat()
  Dog->Cook()
  Dog->Eat()
  而且Eat和Cook的参数还可以有Meat和Bone两种*/

class Food;
class Meat;
class Bone;

class Visitor{
public:
   virtual void visit(Meat *meat) = 0;
   virtual void visit(Bone *bone) = 0;
};

class Food{
public:
   virtual void Accept(Visitor *vis) = 0;
};

class Meat:public Food{
public:
   virtual void Accept(Visitor *vis) {
      vis->visit(this);
   }
};

class Bone:public Food{
public:
   virtual void Accept(Visitor *vis) {
      vis->visit(this);
   }
};


class TigerVisitor:public Visitor{
public:
   virtual void visit(Meat *meat) {
      cout<<"Tiger want to visit meat"<<endl;
   }
   virtual void visit(Bone *bone) {
      cout<<"Tiger want to visit bone"<<endl;
   }
};

class DogVisitor:public Visitor{
public:
   virtual void visit(Meat *meat) {
      cout<<"Dog want to visit meat"<<endl;
   }
   virtual void visit(Bone *bone) {
      cout<<"Dog want to visit bone"<<endl;
   }
};

class TigerEatVisitor:public TigerVisitor{
public:
   virtual void visit(Meat *meat) {
      cout<<"Tiger want to visit meat and eat it"<<endl;
   }
   virtual void visit(Bone *bone) {
      cout<<"Tiger want to visit bone and eat it"<<endl;
   }
};

class TigerCookVisitor:public TigerVisitor{
public:
   virtual void visit(Meat *meat) {
      cout<<"Tiger want to visit meat and cook it"<<endl;
   }
   virtual void visit(Bone *bone) {
      cout<<"Tiger want to visit bone and cook it"<<endl;
   }
};

class DogEatVisitor:public DogVisitor{
public:
   virtual void visit(Meat *meat) {
      cout<<"Dog want to visit meat and eat it"<<endl;
   }
   virtual void visit(Bone *bone) {
      cout<<"Dog want to visit bone and eat it"<<endl;
   }
};

class DogCookVisitor:public DogVisitor{
public:
   virtual void visit(Meat *meat) {
      cout<<"Dog want to visit meat and cook it"<<endl;
   }
   virtual void visit(Bone *bone) {
      cout<<"Dog want to visit bone and cook it"<<endl;
   }
};

int main() {
   Food *m = new Meat();
   Food *b = new Bone();
   Visitor *tev = new TigerEatVisitor();
   Visitor *tcv = new TigerCookVisitor();
   Visitor *dev = new DogEatVisitor();
   Visitor *dcv = new DogCookVisitor();
   m->Accept(tcv);
   m->Accept(tev);
   m->Accept(dcv);
   m->Accept(dev);
   b->Accept(tcv);
   b->Accept(tev);
   b->Accept(dcv);
   b->Accept(dev);
   delete tev;
   delete tcv;
   delete dev;
   delete dcv;
   delete m;
   delete b;
   return 0;
}

桥接模式,代理模式,中介着模式,命令模式的区别

1. 我们可以看出,中介者模式和代理模式和命令模式比较相似,他们强调的是通信,桥接模式强调的时候拥有属性;
2. 中介者模式是多对多通信,代理是一对一通信,桥接是一对多,命令模式是多对多通信;
3. 代理是通信只能从一方到另外一方,中介者是双向都可以通信;
4. 中介者和代理模式一般接口是固定的(即请求比较固定),而命令模式请求一般不固定,可能会改变,所以将命令进行对象化和独立化使得代码更加灵活;

另外还有策略模式和桥接模式其实也很像,他们的区别就是,策略是针对某一个算法而言,而桥接可适应的变化更多


纪念没有听过课,仅仅看了四天书的和网上各种资料的结果。坑爹的选修课,原来开卷是让你写整整2个多小时的代码。。。。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值