c++设计模式之命令模式

命令模式:
场景:
对一个对象要进行很多动作,每个动作就是一个命令。在原有的逻辑中,需要在客户端写出许多分支语句,针对内个动作,调用该对象类的成员函数。每增加一个动作,都需要在客户端和对象类中修改代码。违背了高内聚,低耦合的原则。因此,对于这种情况就可以使用命令模式。
组成元素:
1.抽象命令类
2.具体命令类(动作)
3.接受者(接受动作的对象)
4.装配者,增加删除命令,从而形成命令链
结构: 1.抽象命令类:很多动作,那么都需要有很多命令类,为了代码层次性更好,最好抽象出一个抽象的命令类。该类应该有一个执行函数,子类继承该函数(excute函数),在该成员函数中,调用接受者的成员函数,因此在抽象命令类中应该有一个接受者成员变量
2.具体命令类:继承具体抽象类,执行具体的动作
3.接受者:针对具体的命令编写具体的执行成员函数
4.装配者:增加或者删除命令对象,形成命令链

  1 //Paint.h
  2 #pragma once
  3 #include <iostream>
  4 using namespace std;
  5 class Picture
  6 {
  7 public:
  8     Picture();
  9     ~Picture();
 10     void Rotate();
 11     void Translation();
 12     void Stretch();
 13 };
 14 
 15 //Paint.cpp
 16 #include "pch.h"
 17 #include "Paint.h"
 18 
 19 
 20 Picture::Picture()
 21 {
 22 }
 23 
 24 
 25 Picture::~Picture()
 26 {
 27 }
 28 
 29 void Picture::Rotate() 
 30 {
 31     cout << "rotate" << endl;
 32 }
 33 
 34 void Picture::Translation() 
 35 {
 36     cout << "translation" << endl;
 37 }
 38 
 39 void Picture::Stretch() 
 40 {
 41     cout << "stretch" << endl;
 42 }
 43 
 44 //ICommand.h
 45 #pragma once
 46 #include <iostream>
 47 #include "Paint.h"
 48 using namespace std;
 49 
 50 class ICommand
 51 {
 52 public:
 53     ICommand(Picture* picture);
 54     ~ICommand();
 55 protected:
 56     Picture* picture_;
 57 public:
 58     virtual void excute() = 0;
 59 };
 60 
 61 
 62 class CmdRotate:public ICommand
 63 {
 64 public:
 65     CmdRotate(Picture* picture);
 66     void excute();
 67 };
 68 
 69 class CmdTranslation:public ICommand
 70 {
 71 public:
 72     CmdTranslation(Picture* picture);
 73     void excute();
 74 };
 75 
 76 class CmdStretch:public ICommand
 77 {
 78 public:
 79     CmdStretch(Picture* picture);
 80     void excute();
 81 };
 82 
 83 //ICommand.cpp
 84 #include "pch.h"
 85 #include "ICommand.h"
 86 
 87 
 88 ICommand::ICommand(Picture* picture)
 89 {
 90 }
 91 
 92 
 93 ICommand::~ICommand()
 94 {
 95 }
 96 
 97 CmdRotate::CmdRotate(Picture* picture) :ICommand(picture) {}
 98 
 99 void CmdRotate::excute() 
100 {
101     picture_->Rotate();
102 }
103 
104 CmdTranslation::CmdTranslation(Picture* picture) :ICommand(picture) {}
105 
106 void CmdTranslation::excute() 
107 {
108     picture_->Translation();
109 }
110 
111 
112 CmdStretch::CmdStretch(Picture* picture) :ICommand(picture) {}
113 
114 void CmdStretch::excute() 
115 {
116     picture_->Stretch();
117 }
118 
119 //Invoker.h
120 #pragma once
121 #include <list>
122 #include "ICommand.h"
123 class Invoker
124 {
125 public:
126     Invoker();
127     ~Invoker();
128     void AddCmd(ICommand* cmd);
129     void RemoveCmd(ICommand* cmd);
130     void notify();
131 private:
132     std::list<ICommand*> cmd_list;
133 };
134 
135 //Invoker.cpp
136 #include "pch.h"
137 #include "Invoker.h"
138 
139 
140 Invoker::Invoker()
141 {
142 }
143 
144 
145 Invoker::~Invoker()
146 {
147 }
148 
149 void Invoker::AddCmd(ICommand* cmd) 
150 {
151     cmd_list.push_back(cmd);
152 }
153 
154 void Invoker::RemoveCmd(ICommand* cmd) 
155 {
156     cmd_list.remove(cmd);
157 }
158 
159 void Invoker::notify() 
160 {
161     std::list<ICommand*>::iterator it = cmd_list.begin();
162     for (;it!=cmd_list.end();it++)
163     {
164         (*it)->excute();
165     }
166 }
167 
168 //main.cpp
169 #include "pch.h"
170 #include <iostream>
171 #include "ICommand.h"
172 #include "Paint.h"
173 #include "Invoker.h"
174 using namespace std;
175 
176 
177 #define SAFE_DELETE(p){ if(p){delete(p);(p)=NULL; } }
178 
179 int main()
180 {
181     Picture* picture = new Picture;
182     ICommand* rotate_cmd = new CmdRotate(picture);
183     ICommand* translation_cmd = new CmdTranslation(picture);
184     ICommand* stretch_cmd = new CmdStretch(picture);
185 
186     Invoker* invo = new Invoker;
187     invo->AddCmd(rotate_cmd);
188     invo->AddCmd(translation_cmd);
189     invo->AddCmd(stretch_cmd);
190 
191     invo->notify();
192 
193     SAFE_DELETE(picture);
194     SAFE_DELETE(rotate_cmd);
195     SAFE_DELETE(translation_cmd);
196     SAFE_DELETE(stretch_cmd);
197     SAFE_DELETE(invo);
198 
199     getchar();
200 }

运行结果:

原文地址:https://www.cnblogs.com/HPAHPA/p/10284606.html