zoukankan      html  css  js  c++  java
  • 17行为型模式之命令模式

    概念

      Command模式也叫命令模式 ,是行为设计模式的一种。Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。

      在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。

      但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。

      整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。-

      调用前后需要对调用参数进行某些处理。调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。

    角色和职责

    Command

      Command命令的抽象类。

    ConcreteCommand

             Command的具体实现类。

    Receiver

             需要被调用的目标对象。

    Invorker

             通过Invorker执行Command对象。

    适用于:

             是将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

    案例

    //根据输入不同的命令,出售不同的水果

    #include <iostream>
    using namespace std;
    #include "list"
    
    class Vendor
    {
    public:
    	void sailbanana()
    	{
    		cout << "卖香蕉" << endl;
    	}
    	void sailapple()
    	{
    		cout << "卖苹果" << endl;
    	}
    };
    
    class Command
    {
    public:
    	virtual void sail() = 0;
    };
    
    class BananaCommand : public Command
    {
    public:
    	BananaCommand(Vendor *v)
    	{
    		m_v = v;
    	}
    	Vendor *getV(Vendor *v)
    	{
    		return m_v;
    	}
    
    	void setV(Vendor *v)
    	{
    		m_v = v;
    	}
    	virtual void sail()
    	{
    		m_v->sailbanana();
    	}
    protected:
    private:
    	Vendor *m_v;
    };
    
    class AppleCommand : public Command
    {
    public:
    	AppleCommand(Vendor *v)
    	{
    		m_v = v;
    	}
    	Vendor *getV(Vendor *v)
    	{
    		return m_v;
    	}
    
    	void setV(Vendor *v)
    	{
    		m_v = v;
    	}
    	virtual void sail()
    	{
    		m_v->sailapple();
    	}
    protected:
    private:
    	Vendor *m_v;
    };
    
    class Waiter
    {
    public:
    	Command *getCommand()
    	{
    		return m_command;
    	}
    	void setCommand(Command *c)
    	{
    		m_command = c;
    	}
    	void sail()
    	{
    		m_command->sail();
    	}
    protected:
    private:
    	Command *m_command;
    };
    
    class AdvWaiter
    {
    public:
    	AdvWaiter()
    	{
    		m_list = new list<Command *>;
    		m_list->resize(0);
    	}
    	~AdvWaiter()
    	{
    		delete m_list;
    	}
    	void setCommands(Command *c)
    	{
    		m_list->push_back(c);
    	}
    	list<Command *> * getCommands()
    	{
    		return m_list;
    	}
    	void sail()
    	{
    		for (list<Command *>::iterator it=m_list->begin(); it!=m_list->end(); it++ )
    		{
    			(*it)->sail();
    		}
    	}
    protected:
    private:
    	list<Command *> *m_list;
    };
    
    //小商贩 直接 卖 水果
    void main25_01()
    {
    	Vendor *v = new Vendor;
    	v->sailapple();
    	v->sailbanana();
    
    	delete v;
    	return ;
    }
    
    //小商贩 通过命令 卖 水果
    void main25_02()
    {
    	Vendor *v = new Vendor;
    	AppleCommand *ac = new AppleCommand(v);
    	ac->sail();
    
    	BananaCommand *bc = new BananaCommand(v);
    	bc->sail();
    
    	delete bc;
    	delete ac;
    	delete v;
    }
    
    //小商贩 通过waiter 卖 水果
    void main25_03()
    {
    	Vendor *v = new Vendor;
    	AppleCommand *ac = new AppleCommand(v);
    	BananaCommand *bc = new BananaCommand(v);
    
    	Waiter *w = new Waiter;
    	w->setCommand(ac);
    	w->sail();
    
    	w->setCommand(bc);
    	w->sail();
    
    	delete w;
    	delete bc;
    	delete ac;
    	delete v;
    }
    
    //小商贩 通过advwaiter 批量下单 卖水果
    void main25_04()
    {
    	Vendor *v = new Vendor;
    	AppleCommand *ac = new AppleCommand(v);
    	BananaCommand *bc = new BananaCommand(v);
    
    	AdvWaiter *w = new AdvWaiter;
    	w->setCommands(ac);
    	w->setCommands(bc);
    	w->sail();
    
    	delete w;
    	delete bc;
    	delete ac;
    	delete v;
    }
    
    void main()
    {
    	//main25_01();
    	//main25_02();
    	//main25_03();
    	main25_04();
    	system("pause");
    }
    

      

  • 相关阅读:
    leecode 91. 解码方法
    leecode 166. 分数到小数
    剑指 Offer 31. 栈的压入、弹出序列
    leecode 386. 字典序排数
    LeetCode 311 稀疏矩阵的乘法
    leecode 89. 格雷编码
    leecode 79. 单词搜索
    leecode 207. 课程表
    QT -- 解决:Error: Could not decode "*.cpp" with "UTF-8"
    VS+QT -- 没有PRO文件的问题
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/10358022.html
Copyright © 2011-2022 走看看