【嵌入式c++】设计模式之命令模式(Command)

题目描述:

Command

动机(Motivation)

  • ”行为请求者“与”行为实现者“通常呈现一种”紧耦合“。但在某些场合——比如需要对行为进行”记录、撤销、事务“等处理,这种无法抵御变化的紧耦合是不合适的。
  • 在这种情况下,如何将”行为请求者“与”行为实现者“解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

模式定义

将一个请求(行为)封装成一个对象,从而使你可用不用的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
——《设计模式》GoF

要点总结

  • Command模式的根本目的在于将”行为请求者“与”行为实现者“解耦,在面向对象语言中,常见的实现手段是”将行为抽象为对象“。
  • 与C++中的函数对象类似,C++函数对象以函数签名来定义行为接口规范,更灵活性能更高。

代码结构

.
├── build.sh
├── clearBuild.sh
├── CMakeLists.txt
├── src 
│   ├── examStu.cpp
│   ├── include
│   │   └── examStu.h
│   └── main.cpp

源码例子

examStu.h

#ifndef _EXANSTU__

\#define _EXANSTU__



\#include <iostream>

\#include <string>

\#include <vector>

\#include <list>

using namespace std;

class chef

{
    
    

public:

  chef()=default;

  void MakeNoodles()

  {
    
    

​    cout<< "chef Make Noodles "<<endl;

  }

  void MakePizza()

  {
    
    

​    cout<< "chef Make Pizza "<<endl;    

  }

private:

};

class CookCommand

{
    
    

public:

  CookCommand(chef* p):pchef(p){
    
    }

  virtual ~CookCommand(){
    
    };

  virtual void ExecuteCommand() = 0;



protected:

  chef * pchef;



};

class NoodlesCommand:public CookCommand

{
    
    

public:

  NoodlesCommand(chef * p):CookCommand(p){
    
    }

  void ExecuteCommand()

  {
    
    

​    pchef->MakeNoodles();

  }

private:

};

class PizzaCommand:public CookCommand

{
    
    

public:

  PizzaCommand(chef * p):CookCommand(p){
    
    }

  void ExecuteCommand()

  {
    
    

​    pchef->MakePizza();

  }

private:

};



class Waiter

{
    
    

public:

  Waiter()=default;

  ~Waiter(){
    
    };

  void AddCommand(CookCommand * pCmd)

  {
    
    

​    pCmdVec.push_back(pCmd);

  }

  void submitCmd()

  {
    
    for(auto it=pCmdVec.begin();it!=pCmdVec.end();it++){
    
    (*it)->ExecuteCommand();}

  }

private:

  std::vector<CookCommand *> pCmdVec;

};

#endif

main.cpp

#include <iostream>

\#include <string>

\#include <memory>
\#include "examStu.h"
using namespace std;

int main()
{
  Waiter * pWaiter= new Waiter();
  chef * pchef= new chef();
  CookCommand * pNoodlesCommand= new NoodlesCommand(pchef);
  CookCommand * pPizzaCommand= new PizzaCommand(pchef);
  pWaiter->AddCommand(pNoodlesCommand);
  pWaiter->AddCommand(pPizzaCommand);
  pWaiter->submitCmd();
  delete pWaiter;
  delete pchef;
  delete pNoodlesCommand;
  delete pPizzaCommand;
  return 0;
}

另外一种写法如下:

examStu.c

#ifndef _EXANSTU__
#define _EXANSTU__

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

class chef
{
    
    
public:
    chef()=default;
    void MakeNoodles()
    {
    
    
        cout<< "chef Make Noodles "<<endl;
    }
    void MakePizza()
    {
    
    
        cout<< "chef Make Pizza "<<endl;        
    }

private:

};

class CookCommand
{
    
    
public:
    CookCommand(){
    
    }
    virtual ~CookCommand(){
    
    };
    virtual void ExecuteCommand() = 0;

protected:

};

class NoodlesCommand:public CookCommand
{
    
    
public:
    NoodlesCommand(chef * p):pchef(p){
    
    }
    void ExecuteCommand()
    {
    
    
        pchef->MakeNoodles();
    }
private:
    chef * pchef;
};

class PizzaCommand:public  CookCommand
{
    
    
public:
    PizzaCommand(chef * p):pchef(p){
    
    }
    void ExecuteCommand()
    {
    
    
        pchef->MakePizza();
    }
private:
    chef * pchef;
};





class Waiter
{
    
    
public:
    Waiter()=default;
    ~Waiter(){
    
    };
    void AddCommand(CookCommand * pCmd)
    {
    
    
        pCmdVec.push_back(pCmd);
    }
    void submitCmd()
    {
    
    
        for(auto it=pCmdVec.begin();it!=pCmdVec.end();it++)
        {
    
    
            (*it)->ExecuteCommand();
        }

    }
private:


    std::vector<CookCommand *> pCmdVec;

};


#endif

main.c

#include <iostream>
#include <string>
#include <memory>

#include "examStu.h"

using namespace std;


int main()
{
    
    

    Waiter * pWaiter= new Waiter();
    chef * pchef= new chef();
    CookCommand  * pNoodlesCommand= new NoodlesCommand(pchef);
    CookCommand  * pPizzaCommand= new PizzaCommand(pchef);

    pWaiter->AddCommand(pNoodlesCommand);
    pWaiter->AddCommand(pPizzaCommand);

    pWaiter->submitCmd();

    delete pWaiter;
    delete pchef;
    delete pNoodlesCommand;
    delete pPizzaCommand;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_15555275/article/details/109467767