其实命令模式百度已经解释的非常全面了,这里粘贴下来再对照大话设计模式C++版中的例子,供自己学习参考用。
1.概述
在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)。
2.模式分析
1)命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
2)每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
3)命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
4)命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
5)命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。
3.优缺点
优点:
1)降低对象之间的耦合度。
2)新的命令可以很容易地加入到系统中。
3)可以比较容易地设计一个组合命令。
4)调用同一方法实现不同的功能
缺点:
1)使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
4.适用环境
1)系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2)系统需要在不同的时间指定请求、将请求排队和执行请求。
3)系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4)系统需要将一组操作组合在一起,即支持宏命令。
5.代码
《大话设计模式C++版》
1 #include "stdafx.h" 2 #include <iostream> 3 #include <string> 4 using namespace std; 5 6 // 请求 7 class Request 8 { 9 public: 10 int m_nNumber; 11 }; 12 13 // 管理者 14 class Manager 15 { 16 public: 17 Manager(string temp) { name = temp; } 18 void SetSuccessor(Manager* temp) { manager = temp; } 19 virtual void GetRequest(Request* request) = 0; 20 protected: 21 Manager* manager; 22 string name; 23 }; 24 25 // 经理 26 class CommonManager : public Manager 27 { 28 public: 29 CommonManager(string strTemp) : Manager(strTemp) {} 30 virtual void GetRequest(Request* request) 31 { 32 if (request->m_nNumber>=0 && request->m_nNumber<1000) 33 { 34 cout << name << " 处理了请求: " << request->m_nNumber << endl; 35 } 36 else 37 { 38 manager->GetRequest(request); 39 } 40 } 41 }; 42 43 // 总监 44 class Majordomo : public Manager 45 { 46 public: 47 Majordomo(string strTemp) : Manager(strTemp) {} 48 virtual void GetRequest(Request* request) 49 { 50 if (request->m_nNumber <= 5000) 51 { 52 cout << name << " 处理了请求: " << request->m_nNumber << endl; 53 } 54 else 55 { 56 manager->GetRequest(request); 57 } 58 } 59 }; 60 61 //总经理 62 class GeneralManager: public Manager 63 { 64 public: 65 GeneralManager(string name):Manager(name) {} 66 virtual void GetRequest(Request* request) //总经理可以处理所有请求 67 { 68 cout << name << " 处理了请求: " << request->m_nNumber << endl; 69 } 70 }; 71 72 int main() 73 { 74 Manager* common = new CommonManager("张经理"); 75 Manager* major = new Majordomo("李总监"); 76 GeneralManager* general = new GeneralManager("赵总"); 77 // common对象的SetSuccessor函数中传递major对象的引用, 78 // 当common对象能够处理时就处理,不能处理时传递给major对象处理 79 // 同样majar对象的SetSuccessor函数中传递general对象的引用 80 // 当majar对象能够处理时就处理,不能处理时传递给general对象处理 81 common->SetSuccessor(major); 82 major->SetSuccessor(general); 83 Request* rq = new Request(); 84 85 rq->m_nNumber = 999; 86 common->GetRequest(rq); 87 88 rq->m_nNumber = 4999; 89 common->GetRequest(rq); 90 91 rq->m_nNumber = 6999; 92 common->GetRequest(rq); 93 94 delete rq; 95 delete major; 96 delete common; 97 delete general; 98 99 system("pause"); 100 return 0; 101 }