C++设计模式-Command命令模式

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

由于“行为请求者”与“行为实现者”的紧耦合,使用命令模式,可以对请求排队或记录请求日志,以及支持可撤销的操作。

UML图:


Command类,用来声明执行操作的接口

ConcreteCommand,将一个接收者对象绑定于一个操作,调用接收者相应的操作,以实现Execute

Invoker类,要求该命令执行这个请求

Receiver类,知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者。

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

Command模式结构图中,将请求的接收者(处理者)放到Command的具体子类ConcreteCommand中,当请求到来时(Invoker发出Invoke消息激活Command对象),ConcreteCommand将处理请求交给Receiver对象进行处理。

命令模式的优点:
1,它能较容易地设计一个命令队列;
2,在需要的情况下,可以较容易地将命令记入日志;
3,允许接收请求的一方决定是否要否决请求。
4,可以容易地实现对请求的撤销和重做;
5,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。

命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。

Command模式关键就是讲一个请求封装到一个类中(Command),再提供处理对象(Receiver),最后Command命令由Invoker激活。另外,我们可以将请求接收者的处理抽象出来作为参数传给Command对象,实际也就是回调的机制来实现这一点。也就是讲处理操作方法地址通过参数传递给Command对象,Command对象在适当的时候再调用该函数。

Command模式将调用操作的对象和知道如何实现该操作的对象解耦,在上面Command的结构图中,Invoker对象根本就不知道具体的是哪个对象在处理Execute操作(当然要知道是Command类别的对象)。
在Command要增加新的处理操作对象很容易,我们可以通过创建新的继承自Command的子类来实现这一点。
Command模式可以和Memento模式结合起来,支持取消的操作。

代码如下:

Command.h

 1 #ifndef _COMMAND_H_
 2 #define _COMMAND_H_
 3
 4 class Command
 5 {
 6 public:
 7     virtual ~Command();
 8     virtual void Execute()=0;
 9 protected:
10     Command();
11 private:
12 };
13
14 class Receiver;
15
16 class ConcreteCommand : public Command
17 {
18 public:
19     ConcreteCommand(Receiver* pReceiver);
20     ~ConcreteCommand();
21     virtual void Execute();
22 protected:
23 private:
24     Receiver* _recv;
25 };
26
27 class Invoker
28 {
29 public:
30     Invoker(Command* pCommand);
31     ~Invoker();
32     void Invoke();
33 protected:
34 private:
35     Command* _cmd;
36 };
37
38 class Receiver
39 {
40 public:
41     Receiver();
42     ~Receiver();
43     void Action();
44 protected:
45 private:
46 };
47 #endif

Command.cpp

 1 #include "Command.h"
 2 #include <iostream>
 3
 4 using namespace std;
 5
 6 Command::Command()
 7 {}
 8
 9 Command::~Command()
10 {}
11
12 ConcreteCommand::ConcreteCommand(Receiver* pReceiver)
13 {
14     this->_recv = pReceiver;
15 }
16
17 ConcreteCommand::~ConcreteCommand()
18 {}
19
20 void ConcreteCommand::Execute()
21 {
22     this->_recv->Action();
23 }
24
25 Receiver::Receiver()
26 {}
27
28 Receiver::~Receiver()
29 {}
30
31 void Receiver::Action()
32 {
33     cout << "Receiver::Action" << endl;
34 }
35
36 Invoker::Invoker(Command* pCommand)
37 {
38     this->_cmd = pCommand;
39 }
40
41 Invoker::~Invoker()
42 {}
43
44 void Invoker::Invoke()
45 {
46     this->_cmd->Execute();
47 }

main.cpp

 1 #include "Command.h"
 2
 3 int main()
 4 {
 5     //创建具体命令对象pCmd并设定它的接收者pRev
 6     Receiver* pRev = new Receiver();
 7     Command* pCmd = new ConcreteCommand(pRev);
 8     //请求绑定命令
 9     Invoker* pInv = new Invoker(pCmd);
10     pInv->Invoke();
11
12     return 0;
13 }
时间: 2024-08-28 02:07:21

C++设计模式-Command命令模式的相关文章

[C++设计模式] command 命令模式

在软件系统中,"行为请求者"与"行为实现者"通常呈现一种"紧耦合".但在某些场合,比如要对行为进行"记录.撤销/重做.事务"等处理,这种无法抵御变化的紧耦合是不合适的.在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,实现二者之间的松耦合.这就是命令模式(Command Pattern). 在OOP中,一切都是对象,将请求封装成对象,符合OOP的设计思想,当将

设计模式14:Command 命令模式(行为型模式)

Command 命令模式(行为型模式) 耦合与变化 耦合是软件不能抵御变化的根本性原因.不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系. 动机(Motivation) 在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合——比如对行为进行“记录.撤销/重做(undo/redo).事务”等处理,这种无法抵御变化的紧耦合是不合适的. 在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的解耦. 意

设计模式(十四):Command命令模式 -- 行为型模式

1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活. 例子1:电视机遥控器 : 遥控器是请求的发送者,电视机是请求的接收者,遥控器上有一些按钮如开,关,换频道等按钮就是具体命令,不同的按钮对应电视机的不同操作. 2.问题 在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧

设计模式之命令模式(Command)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化托付给还有一个对象.创建型模式有两个不断出现的主旋律. 第一,它们都将关于该系统使用哪些详细的类的信息封装起来.第二.它们隐藏了这些类的实例是怎样被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口. 因此.创建型模式在什么被创建.谁创建它,它是怎样被创建

设计模式 ( 十三 ) 命令模式Command(对象行为型)

设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活. 例子1:电视机遥控器 : 遥控器是请求的发送者,电视机是请求的接收者,遥控器上有一些按钮如开,关,换频道等按钮就是具体命令,不同的按钮对应电视机的不同操作. 2.问题

C#设计模式(15)——命令模式(Command Pattern)

原文:C#设计模式(15)--命令模式(Command Pattern) 一.前言 之前一直在忙于工作上的事情,关于设计模式系列一直没更新,最近项目中发现,对于设计模式的了解是必不可少的,当然对于设计模式的应用那更是重要,可以说是否懂得应用设计模式在项目中是衡量一个程序员的技术水平,因为对于一个功能的实现,高级工程师和初级工程师一样都会实现,但是区别在于它们实现功能的可扩展和可维护性,也就是代码的是否“优美”.可读.但是,要更好地应用,首先就必须了解各种设计模式和其应用场景,所以我还是希望继续完

GOF23设计模式之命令模式(Command)的理解与实现

 命令模式Command      命令模式:将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化:对请求排毒或者记录请求日志,以及支持可撤销的操作.也称之为:动作Action模式,事务Transaction模式   结构:      Command抽象命令类      ConcreteCommand具体命令类      Invoker调用者/请求者          请求的发送者,它通过命令对象来执行请求,一个调用者并不需要在设计时确定其接收者.因此它至于抽象命令类之间存在惯

Java设计模式(六) Command(命令模式)及Tomcat引申

基本概念 Command 命令模式是一个高内聚的模式(满足单一职责原则) 概念:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 命令模式在项目中频繁使用,封装性和拓展性都有很好的保障 Command模式中的角色分工: Client:创建一个命令并决定接受者 Command:命令接口,定义一个抽象方法 Concrete Command:具体命令,负责调用接受者的相关操作 Invoker:请求者,负责调用命令对象执行请求 R

设计模式之命令模式

命令模式的核心是把方法调用封装起来,调用的对象不需要关心是如何执行的. 定义:命令模式将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也可以支持撤销操作. 先看一个例子,设计一个家电遥控器的API,可以通过遥控器发出命令来控制不同生产商生产的家电,比如关灯.开灯. 以下是一个简单的代码示例. 1 package cn.sp.test05; 2 /** 3 * 电灯类 4 * @author 2YSP 5 * 6 */ 7 public class Lig