命令模式

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 }

 

posted @ 2020-04-14 13:06  三岁玩童  阅读(139)  评论(0编辑  收藏  举报