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 }
运行结果: