命令模式

  其实命令模式百度已经解释的非常全面了,这里粘贴下来再对照大话设计模式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 }
原文地址:https://www.cnblogs.com/SnailProgramer/p/4275143.html