Headfirst设计模式的C++实现——命令模式(Command)
先看如果不用命令模式的实现:
light.h
1 #ifndef _LIGHT_H_ 2 #define _LIGHT_H 3 4 #include <iostream> 5 6 class LIGHT { 7 public: 8 void on() { std::cout << "light is on" << std::endl; } 9 void off() { std::cout << "light is off" << std::endl; } 10 }; 11 12 #endif
tv.h
1 #ifndef _TV_H_ 2 #define _TV_H_ 3 4 #include <iostream> 5 6 class TV { 7 public: 8 void open() { std::cout << "TV is opened" << std::endl; } 9 void close() { std::cout << "TV is closed" << std::endl; } 10 }; 11 #endif
remote.h
1 #ifndef _REMOTE_H_ 2 #define _REMOTE_H_ 3 4 #include <string> 5 #include <iostream> 6 #include "tv.h" 7 #include "light.h" 8 9 class REMOTE { 10 public: 11 void set(int slot, const std::string& device) { 12 if ( slot < MAX_SLOT_NUM ) { 13 all_device[slot] = device; 14 } 15 } 16 17 void press_on_button(int slot) { 18 if ( slot >= MAX_SLOT_NUM ) { 19 return; 20 } 21 if ( all_device[slot] == "" ) { 22 std::cout << "slot " << slot << " is empty" << std::endl; 23 } 24 else { 25 if ( "TV" == all_device[slot] ) { 26 TV tv; 27 tv.open(); 28 } 29 else if ( "LIGHT" == all_device[slot] ) { 30 LIGHT light; 31 light.on(); 32 } 33 else { 34 std::cout << "invalid type" << std::endl; 35 } 36 } 37 } 38 39 void press_off_button(int slot) { 40 if ( slot >= MAX_SLOT_NUM ) { 41 return; 42 } 43 if ( all_device[slot] == "" ) { 44 std::cout << "slot " << slot << " is empty" << std::endl; 45 } 46 else { 47 if ( "TV" == all_device[slot] ) { 48 TV tv; 49 tv.close(); 50 } 51 else if ( "LIGHT" == all_device[slot] ) { 52 LIGHT light; 53 light.off(); 54 } 55 else { 56 std::cout << "invalid type" << std::endl; 57 } 58 59 } 60 } 61 private: 62 const static int MAX_SLOT_NUM = 7; 63 std::string all_device[MAX_SLOT_NUM]; 64 }; 65 66 #endif
main.cpp
1 #include "remote.h" 2 int main() { 3 REMOTE remote; 4 remote.set(0, "TV"); 5 remote.set(1, "LIGHT"); 6 remote.press_on_button(0); 7 remote.press_off_button(1); 8 remote.press_on_button(2); 9 }
再看看使用命令模式的实现
light.h和tv.h不变
command.h
1 #ifndef _COMMAND_H_ 2 #define _COMMAND_H_ 3 4 class COMMAND { 5 public: 6 virtual void execute() = 0; 7 }; 8 9 #endif
light_on_command.h
1 #ifndef _LIGHT_ON_COMMAND_H_ 2 #define _LIGHT_ON_COMMAND_H_ 3 4 #include "command.h" 5 #include "light.h" 6 7 class LIGHT_ON_COMMAND : public COMMAND { 8 private: 9 LIGHT &light; 10 public: 11 LIGHT_ON_COMMAND( LIGHT &_light ) : light(_light) {} 12 void execute() { light.on(); } 13 }; 14 15 #endif
light_off_command.h
1 #ifndef _LIGHT_OFF_COMMAND_H_ 2 #define _LIGHT_OFF_COMMAND_H_ 3 4 #include "command.h" 5 #include "light.h" 6 7 class LIGHT_OFF_COMMAND : public COMMAND { 8 private: 9 LIGHT &light; 10 public: 11 LIGHT_OFF_COMMAND( LIGHT &_light ) : light(_light) {} 12 void execute() { light.off(); } 13 }; 14 15 #endif
tv_on_command.h
1 #ifndef _TV_ON_COMMAND_H_ 2 #define _Tv_ON_COMMAND_H_ 3 4 #include "command.h" 5 #include "tv.h" 6 7 class TV_ON_COMMAND : public COMMAND { 8 private: 9 TV &tv; 10 public: 11 TV_ON_COMMAND( TV&_tv) : tv(_tv) {} 12 void execute() { tv.open(); } 13 }; 14 15 #endif
tv_off_command.h
1 #ifndef _TV_OFF_COMMAND_H_ 2 #define _TV_OFF_COMMAND_H_ 3 4 #include "command.h" 5 #include "tv.h" 6 7 class TV_OFF_COMMAND : public COMMAND { 8 private: 9 TV &tv; 10 public: 11 TV_OFF_COMMAND( TV&_tv) : tv(_tv) {} 12 void execute() { tv.close(); } 13 }; 14 15 #endif
remote.h
1 #ifndef _REMOTE_H_ 2 #define _REMOTE_H_ 3 4 #include "command.h" 5 #include <iostream> 6 7 class REMOTE { 8 public: 9 REMOTE() { 10 for ( int i = 0; i < MAX_SLOT_NUM; i++ ) { 11 on_commands[i] = NULL; 12 off_commands[i] = NULL; 13 } 14 } 15 16 void set(int slot, COMMAND& on_command, COMMAND& off_command) { 17 if ( slot < MAX_SLOT_NUM ) { 18 on_commands[slot] = &on_command; 19 off_commands[slot] = &off_command; 20 } 21 } 22 23 void press_on_button(int slot) { 24 if ( slot < MAX_SLOT_NUM ) { 25 if ( NULL != on_commands[slot] ) { 26 on_commands[slot]->execute(); 27 } 28 else { 29 std::cout << "slot " << slot << " is empty" << std::endl; 30 } 31 } 32 } 33 34 void press_off_button(int slot) { 35 if ( slot < MAX_SLOT_NUM ) { 36 if ( NULL != off_commands[slot] ) { 37 off_commands[slot]->execute(); 38 } 39 else { 40 std::cout << "slot " << slot << " is empty" << std::endl; 41 } 42 } 43 } 44 private: 45 const static int MAX_SLOT_NUM = 7; 46 COMMAND *on_commands[MAX_SLOT_NUM]; 47 COMMAND *off_commands[MAX_SLOT_NUM]; 48 }; 49 50 #endif
main.cpp
1 #include "remote.h" 2 #include "tv_on_command.h" 3 #include "tv_off_command.h" 4 #include "light_on_command.h" 5 #include "light_off_command.h" 6 7 int main() { 8 REMOTE remote; 9 10 TV tv; 11 TV_ON_COMMAND tv_on_command(tv); 12 TV_OFF_COMMAND tv_off_command(tv); 13 remote.set(0, tv_on_command, tv_off_command); 14 15 LIGHT light; 16 LIGHT_ON_COMMAND light_on_command(light); 17 LIGHT_OFF_COMMAND light_off_command(light); 18 remote.set(1, light_on_command, light_off_command); 19 20 remote.press_on_button(0); 21 remote.press_off_button(1); 22 remote.press_on_button(2); 23 }