命令模式
1.操作对象 和 操作一个操作的对象分开;被解耦的两个对象通过命令对象沟通;添加一个命令不影响其他类; 可记录 日志,事务
2.代码
C++
1 //command c++ 2 #include <iostream> 3 #include <vector> 4 #include <string> 5 using namespace std; 6 7 enum WEAPON_MAGIC_TYPE{ KNIFE,SWORD,WAND,FAIR,WIND,ICE_STORM }; 8 typedef int MAGIC_DIMENSION; 9 10 class aSoldier{ 11 public: 12 MAGIC_DIMENSION COST_VALUE = 20; 13 14 aSoldier(string s):name(s){} 15 void changeWeapon(WEAPON_MAGIC_TYPE type) { this->weapen = type; cout<<this->name<<" take weapon:"<<this->weapen<<endl;} 16 WEAPON_MAGIC_TYPE getWeapen() { return this->weapen; } 17 void releaseMagic(WEAPON_MAGIC_TYPE type) { this->magicValue -= COST_VALUE; cout<<this->name<<" release magic:"<<type<<" left magic:"<<this->magicValue<<endl; } 18 int getMagicValue() { return magicValue; } 19 void recover() { this->magicValue += COST_VALUE; cout<<this->name<<" left magic: "<<this->magicValue<<endl; } 20 21 private: 22 string name; 23 WEAPON_MAGIC_TYPE weapen = WEAPON_MAGIC_TYPE::KNIFE; 24 MAGIC_DIMENSION magicValue = 100; 25 }; 26 27 class Command{ 28 public: 29 virtual void setCmd(WEAPON_MAGIC_TYPE) = 0; 30 virtual void execute() = 0; 31 virtual void undo() = 0; 32 }; 33 34 class useMagicCmd : public Command{ 35 public: 36 useMagicCmd(aSoldier* p):m_pSoldier(p){} 37 void setCmd(WEAPON_MAGIC_TYPE argc) { 38 this->useMagic = argc; 39 } 40 void execute(){ 41 m_pSoldier->releaseMagic(this->useMagic); 42 } 43 void undo(){ 44 m_pSoldier->recover(); 45 } 46 private: 47 aSoldier* m_pSoldier; 48 WEAPON_MAGIC_TYPE useMagic; 49 }; 50 51 class changeWeapenCmd : public Command{ 52 public: 53 changeWeapenCmd(aSoldier* p):m_pSoldier(p){} 54 void setCmd(WEAPON_MAGIC_TYPE argc) { 55 lastWeapon = m_pSoldier->getWeapen(); 56 changeWeapon = argc; 57 } 58 void execute(){ 59 m_pSoldier->changeWeapon(changeWeapon); 60 } 61 void undo(){ 62 m_pSoldier->changeWeapon(lastWeapon); 63 } 64 private: 65 aSoldier* m_pSoldier; 66 WEAPON_MAGIC_TYPE lastWeapon; 67 WEAPON_MAGIC_TYPE changeWeapon; 68 }; 69 70 class Control{ 71 public: 72 void setObj(Command* obj){ objVec.push_back(obj); } 73 void notify(){ 74 for(auto c : objVec) 75 c->execute(); 76 77 lastObjVec = objVec; 78 objVec.clear(); 79 } 80 void undo(){ 81 for(auto c : lastObjVec) 82 c->undo(); 83 lastObjVec.clear(); 84 } 85 private: 86 vector<Command*> objVec; 87 vector<Command*> lastObjVec; 88 }; 89 90 int main(){ 91 aSoldier* dragonSolder = new aSoldier("S_S_WanTong"); 92 93 Command* magicCmd = new useMagicCmd(dragonSolder); 94 magicCmd->setCmd(WEAPON_MAGIC_TYPE::ICE_STORM); 95 96 Command* weapenCmd = new changeWeapenCmd(dragonSolder); 97 weapenCmd->setCmd(WEAPON_MAGIC_TYPE::SWORD); 98 99 Control* control = new Control(); 100 control->setObj(weapenCmd); //换剑 101 control->notify(); //执行 102 103 weapenCmd->setCmd(WEAPON_MAGIC_TYPE::WAND); 104 control->setObj(weapenCmd); //换魔杖 105 control->setObj(magicCmd); //释放暴风雪 106 control->notify(); //执行 107 108 control->undo(); //撤销上一步操作 109 110 return 0; 111 }
Java
1 //command java 2 3 interface Command{ 4 public void execute(); 5 public void undo(); 6 } 7 //NoCommand 8 class NoCommand implements Command{ 9 public void execute(){ 10 System.out.println("do nothing"); 11 } 12 public void undo(){} 13 } 14 15 //LightOnCommand 16 class LightOnCommand implements Command{ 17 Light light; 18 public LightOnCommand(Light light){ 19 this.light = light; 20 } 21 public void execute(){ 22 light.on(); 23 } 24 public void undo(){ 25 light.off(); 26 } 27 } 28 //StereoOnWithCDCommand 29 class StereoOnWithCDCommand implements Command{ 30 Stereo stereo; 31 public StereoOnWithCDCommand(Stereo stereo){ 32 this.stereo = stereo; 33 } 34 public void execute(){ 35 stereo.on(); 36 stereo.setCD(); 37 stereo.setVolume(11); 38 } 39 public void undo(){ /* ... */ } 40 } 41 42 // 43 class RemoteControl{ 44 Command[] onCommands; 45 Command[] offCommands; 46 Command undoCommand; 47 48 public RemoteControl(){ 49 onCommands = new Command[7]; 50 offCommands = new Command[7]; 51 52 Command noCommand = new NoCommand(); 53 54 for(int i = 0; i < 7; i++){ 55 onCommands[i] = noCommand; 56 offCommands[i] = noCommand; 57 } 58 undoCommand = noCommand; 59 } 60 public void setCommand(int slot,Command onCommand,Command offCommand){ 61 if(null != onCommand) 62 onCommands[slot] = onCommand; 63 if(null != offCommand) 64 offCommands[slot] = offCommand; 65 } 66 public void onButtonPushed(int slot){ 67 onCommands[slot].execute(); 68 undoCommand = onCommands[slot]; 69 } 70 public void offButtonPushed(int slot){ 71 offCommands[slot].execute(); 72 undoCommand = offCommands[slot]; 73 } 74 public void undoButtonPushed(){ 75 undoCommand.undo(); 76 } 77 public String toString(){ 78 StringBuffer stringBuffer = new StringBuffer(); 79 stringBuffer.append("\n --- Remote Control ---\n"); 80 for(int i = 0; i < onCommands.length; i++){ 81 //not need if(onCommands[i] != null) 82 stringBuffer.append("[slot " + i + " ] " + onCommands[i].getClass().getName()); 83 //if(offCommands[i] != null) 84 stringBuffer.append(" " + offCommands[i].getClass().getName() + "\n"); 85 } 86 return stringBuffer.toString(); 87 } 88 } 89 90 //Light 91 class Light{ 92 private String name; 93 public Light(String name) { this.name = name; } 94 public void on() { System.out.println(this.name + "light on"); } 95 public void off() { System.out.println(this.name + "light off"); } 96 } 97 //stereo 98 class Stereo{ 99 public void on() { System.out.println("stereo on"); } 100 public void setCD() { System.out.println("stereo setCD"); } 101 public void setVolume(int i) { System.out.println("stereo setVolume: " + i); } 102 } 103 104 //main 105 public class RemoteLoader{ 106 public static void main(String[] args){ 107 108 Light livingRoomLight = new Light("Living Room"); 109 Light kitchenLight = new Light("Kitchen"); 110 Stereo stereo = new Stereo(); 111 112 LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight); 113 LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight); 114 StereoOnWithCDCommand stereoOn = new StereoOnWithCDCommand(stereo); 115 116 RemoteControl remoteControl = new RemoteControl(); 117 remoteControl.setCommand(0,livingRoomLightOn,null); 118 remoteControl.setCommand(1,kitchenLightOn,null); 119 remoteControl.setCommand(2,stereoOn,null); 120 121 System.out.println(remoteControl); 122 123 remoteControl.onButtonPushed(0); 124 remoteControl.onButtonPushed(1); 125 remoteControl.undoButtonPushed(); 126 remoteControl.onButtonPushed(2); 127 } 128 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通