將動作執行與接收者包裝到對象裡面,對外暴露的只有一個介面中的execute方法,其他對象不需要知道那個接收者執行了什麼動作,只需要知道調用execute,就能完成一個請求的操作 ...
老闆:阿飛,咱們公司又接了個新項目,一個客戶,,卧室和客廳很大,電燈電視開關也不好找,所以希望製造一個遙控器來控制一些傢具的開啟與關閉,目前需要5個按鍵,卧室的燈,卧室的電視,客廳的燈,客廳的電視,在留一個預備按鍵。我等會把需求文檔給你。
項目組長阿飛:好的,老闆
項目組長阿飛:小三,來了個需求,你看下,你先設計一下架構
阿三:好的,飛哥
三天過後:飛哥,好了,你看下
先設計了一個介面,裡面包含了,每一個按鈕的統一行為
1 package com.commandPattern.command; 2 3 /** 4 * @program: testPattern 5 * @description: 命令介面 6 * @author: Mr.Yang 7 * @create: 2018-12-08 13:54 8 **/ 9 public interface Command { 10 11 //執行方法 12 public void exceute(); 13 14 }View Code
然後建立了一個對象,代表了空對象,什麼操作也不執行
package com.commandPattern.command.nullCommand; import com.commandPattern.command.Command; /** * @program: testPattern * @description: 建立一個空對象,在許多設計模式種,都會看到空對象的使用,甚至有些時候,空對象本身也被視為一種設計模式 * @author: Mr.Yang * @create: 2018-12-08 17:40 **/ public class NullCommand implements Command { public void exceute() { System.out.println("什麼都不做處理"); } }
燈的具體類
package com.commandPattern.entity; /** * @program: testPattern * @description: 燈的具體類 * @author: Mr.Yang * @create: 2018-12-08 17:31 **/ public class Lamp { private String name; /** * name為燈的具體裝飾,即為哪裡的燈 * @param name */ public Lamp(String name){ this.name=name; } public void on (){ System.out.println(name+"_燈打開"); } public void off (){ System.out.println(name+"_燈關閉"); } }
電視的具體類
package com.commandPattern.entity; /** * @program: testPattern * @description: 電視的具體類 * @author: Mr.Yang * @create: 2018-12-08 17:35 **/ public class Tv { private String name; public Tv(String name){ this.name=name; } public void on (){ System.out.println(name+"_電視打開"); } public void off(){ System.out.println(name+"_電視關閉"); } }
關閉燈的具體命令
package com.commandPattern.command.off; import com.commandPattern.command.Command; import com.commandPattern.entity.Lamp; /** * @program: testPattern * @description: 燈關閉 * @author: Mr.Yang * @create: 2018-12-08 17:33 **/ public class LampOffCommand implements Command { Lamp lamp; public LampOffCommand(Lamp lamp){ this.lamp=lamp; } //燈關閉 public void exceute() { lamp.off(); } }
打開燈的具體命令
package com.commandPattern.command.on; import com.commandPattern.command.Command; import com.commandPattern.entity.Lamp; /** * @program: testPattern * @description: 燈打開的命令 * @author: Mr.Yang * @create: 2018-12-08 17:29 **/ public class LampOnCommand implements Command { Lamp lamp; public LampOnCommand(Lamp lamp){ this.lamp=lamp; } //燈打開的命令 public void exceute() { lamp.on(); } }
電視關閉的具體命令
package com.commandPattern.command.off; import com.commandPattern.command.Command; import com.commandPattern.entity.Tv; /** * @program: testPattern * @description: 電視關閉 * @author: Mr.Yang * @create: 2018-12-08 17:36 **/ public class TvOffCommand implements Command { Tv tv; public TvOffCommand(Tv tv){ this.tv=tv; } public void exceute() { tv.off(); } }
電視打開的具體命令
package com.commandPattern.command.on; import com.commandPattern.command.Command; import com.commandPattern.entity.Tv; /** * @program: testPattern * @description: 電視打開 * @author: Mr.Yang * @create: 2018-12-08 17:37 **/ public class TvOnCommand implements Command { Tv tv; public TvOnCommand(Tv tv){ this.tv=tv; } public void exceute() { tv.on(); } }
建立一個遙控器
package com.commandPattern.control; import com.commandPattern.command.Command; import com.commandPattern.command.nullCommand.NullCommand; import java.util.Arrays; /** * @program: testPattern * @description: 遙控器 * @author: Mr.Yang * @create: 2018-12-08 17:39 **/ public class RemoteControl { Command[] onCommand; Command[] offCommand; //初始化每個操作為空操作 public RemoteControl(){ onCommand=new Command[5]; offCommand=new Command[5]; NullCommand nullCommand = new NullCommand(); for (int i = 0; i < 5; i++) { onCommand[i]=nullCommand; offCommand[i]=nullCommand; } } public void setCommond(int index,Command onCommand,Command offCommand){ this.offCommand[index]=offCommand; this.onCommand[index]=onCommand; } public void clickOn(int index){ onCommand[index].exceute(); } public void clickOff(int index){ offCommand[index].exceute(); } /** * 輸出每個按鈕的具體代表類 * @return */ @Override public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < onCommand.length; i++) { sb.append("[index : "+i+"] "); sb.append(onCommand[i].getClass().getName()); sb.append(" "); sb.append(offCommand[i].getClass().getName()); sb.append("\r\n"); } return sb.toString(); } }
測試類
1 package com.commandPattern.testPattern; 2 3 import com.commandPattern.command.off.LampOffCommand; 4 import com.commandPattern.command.off.TvOffCommand; 5 import com.commandPattern.command.on.LampOnCommand; 6 import com.commandPattern.command.on.TvOnCommand; 7 import com.commandPattern.control.RemoteControl; 8 import com.commandPattern.entity.Lamp; 9 import com.commandPattern.entity.Tv; 10 11 /** 12 * @program: test 13 * @description: 14 * @author: Mr.Yang 15 * @create: 2018-12-08 17:48 16 **/ 17 public class TestPattern { 18 public static void main(String[] args) { 19 RemoteControl remoteControl = new RemoteControl(); 20 21 /** 22 * 創建裝置到合適位置 23 */ 24 Tv bedRoomTV = new Tv("卧室"); 25 Tv drawiTV = new Tv("客廳"); 26 27 Lamp bedRoomLamp = new Lamp("卧室"); 28 Lamp drawiLamp = new Lamp("客廳"); 29 30 /** 31 * 創建所有命令操作對象 32 */ 33 //卧室燈關閉對象 34 LampOffCommand bedLampOffCommand = new LampOffCommand(bedRoomLamp); 35 //卧室燈打開對象 36 LampOnCommand bedLampOnCommand = new LampOnCommand(bedRoomLamp); 37 //卧室TV關閉對象 38 TvOffCommand bedTvOffCommand = new TvOffCommand(bedRoomTV); 39 //卧室TV打開對象 40 TvOnCommand bedTVcommand = new TvOnCommand(bedRoomTV); 41 //客廳燈打開對象 42 LampOnCommand drawLampOnCommand = new LampOnCommand(drawiLamp); 43 //客廳燈關閉對象 44 LampOffCommand drawLampOffCommand = new LampOffCommand(drawiLamp); 45 //客廳TV關閉對象 46 TvOffCommand drawTVOffCommand = new TvOffCommand(drawiTV); 47 //客廳TV打開對象 48 TvOnCommand drawTVOnCommand = new TvOnCommand(drawiTV); 49 50 System.out.println("---------------------------------------------未賦值之前------------------------------------------------"); 51 System.out.println(remoteControl); 52 System.out.println("******************************************************************************************************"); 53 54 /** 55 * //將操作對象與卡槽一一對應 56 */ 57 //賦值卧室燈打開與關閉 58 remoteControl.setCommond(0,bedLampOnCommand,bedLampOffCommand); 59 //賦值卧室TV打開與關閉 60 remoteControl.setCommond(1,bedTVcommand,bedTvOffCommand); 61 //賦值客廳燈打開與關閉 62 remoteControl.setCommond(2,drawLampOnCommand,drawLampOffCommand); 63 //賦值客廳TV打開與關閉 64 remoteControl.setCommond(3,drawTVOnCommand,drawTVOffCommand); 65 66 System.out.println("---------------------------------------------賦值之後------------------------------------------------"); 67 System.out.println(remoteControl); 68 System.out.println("******************************************************************************************************"); 69 70 71 /** 72 * 測試每一個按鈕 73 */ 74 remoteControl.clickOn(0); 75 remoteControl.clickOff(0); 76 77 remoteControl.clickOn(1); 78 remoteControl.clickOff(1); 79 80 remoteControl.clickOn(2); 81 remoteControl.clickOff(2); 82 83 remoteControl.clickOn(3); 84 remoteControl.clickOff(3); 85 86 87 } 88 }View Code
測試結果
---------------------------------------------未賦值之前------------------------------------------------ [index : 0] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 1] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 2] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 3] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand ****************************************************************************************************** ---------------------------------------------賦值之後------------------------------------------------ [index : 0] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand [index : 1] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand [index : 2] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand [index : 3] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand [index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand ****************************************************************************************************** 卧室_燈打開 卧室_燈關閉 卧室_電視打開 卧室_電視關閉 客廳_燈打開 客廳_燈關閉 客廳_電視打開 客廳_電視關閉View Code
阿三:飛哥,我這裡使用的設計模式-命令模式,
將動作執行(LampOnCommand,TvOnCommand……)與接收者(Lamp,Tv)包裝到對象裡面,對外暴露的只有一個Command介面中的execute方法,其他對象不需要知道那個接收者執行了什麼動作,只需要知道調用execute,就能完成一個請求的操作,這個對象,與其他對象沒有關聯,完全解耦和,如果需要做新增,不需要修改原有代碼,拓展接收者類和動作執行類,就能實現功能。
項目組長阿飛:不錯,不錯,進步很大。
項目組長阿飛:第5個按鈕可能需要做一個恢覆上一步動作的效果,類似於CTRL+Z這個效果,你再改改把。
阿三:好的。
阿三:飛哥修改好了,你看下
命令介面新增撤銷方法
package com.commandPattern.command; /** * @program: testPattern * @description: 命令介面 * @author: Mr.Yang * @create: 2018-12-08 13:54 **/ public interface Command { //執行方法 public void exceute(); //撤銷方法 public void revoke(); }
建立一個空對象,實現了撤銷方法
package com.commandPattern.command.nullCommand; import com.commandPattern.command.Command; /** * @program: testPattern * @description: 建立一個空對象,在許多設計模式種,都會看到空對象的使用,甚至有些時候,空對象本身也被視為一種設計模式 * @author: Mr.Yang * @create: 2018-12-08 17:40 **/ public class NullCommand implements Command { public void exceute() { System.out.println("什麼都不做處理"); } public void revoke() { System.out.println("什麼都不做處理"); } }
燈關閉實現了撤銷方法
package com.commandPattern.command.off; import com.commandPattern.command.Command; import com.commandPattern.entity.Lamp; /** * @program: testPattern * @description: 燈關閉 * @author: Mr.Yang * @create: 2018-12-08 17:33 **/ public class LampOffCommand implements Command { Lamp lamp; public LampOffCommand(Lamp lamp){ this.lamp=lamp; } //燈關閉 public void exceute() { lamp.off(); } //執行到這個具體實現類,代表上一步是燈關閉,撤銷操作即為燈打開 public void revoke() { lamp.on(); } }
燈打開實現了撤銷方法
package com.commandPattern.command.on; import com.commandPattern.command.Command; import com.commandPattern.entity.Lamp; /** * @program: testPattern * @description: 燈打開的命令 * @author: Mr.Yang * @create: 2018-12-08 17:29 **/ public class LampOnCommand implements Command { Lamp lamp; public LampOnCommand(Lamp lamp){ this.lamp=lamp; } //燈打開的命令 public void exceute() { lamp.on(); } //執行到這個具體實現類,代表上一步是燈打開,撤銷操作即為燈關閉 public void revoke() { lamp.off(); } }
電視關閉實現了撤銷方法
package com.commandPattern.command.off; import com.commandPattern.command.Command; import com.commandPattern.entity.Tv; /** * @program: testPattern * @description: 電視關閉 * @author: Mr.Yang * @create: 2018-12-08 17:36 **/ public class TvOffCommand implements Command { Tv tv; public TvOffCommand(Tv tv){ this.tv=tv; } public void exceute() { tv.off(); } //執行到這個具體實現類,代表上一步是電視關閉,撤銷操作即為電視打開 public void revoke() { tv.on(); } }
電視打開實現了撤銷方法
package com.commandPattern.command.on; import com.commandPattern.command.Command; import com.commandPattern.entity.Tv; /** * @program: testPattern * @description: 電視打開 * @author: Mr.Yang * @create: 2018-12-08 17:37 **/ public class TvOnCommand implements Command { Tv tv; public TvOnCommand(Tv tv){ this.tv=tv; } public void exceute() { tv.on(); } //執行到這個具體實現類,代表上一步是電視打開,撤銷操作即為電視關閉 public void revoke() { tv.off(); } }
遙控器類,新增變數記錄上一步操作
package com.commandPattern.control; import com.commandPattern.command.Command; import com.commandPattern.command.nullCommand.NullCommand; import java.util.Arrays; /** * @program: testPattern * @description: 遙控器 * @author: Mr.Yang * @create: 2018-12-08 17:39 **/ public class RemoteControl { Command[] onCommand; Command[] offCommand; //這個變數來記錄上一個命令 Command upStepCommand; //初始化每個操作為空操作 public RemoteControl(){ onCommand=new Command[5]; offCommand=new Command[5]; NullCommand nullCommand = new NullCommand(); for (int i = 0; i < 5; i++) { onCommand[i]=nullCommand; offCommand[i]=nullCommand; } upStepCommand=nullCommand; } public void setCommond(int index,Command onCommand,Command offCommand){ this.offCommand[index]=offCommand; this.onCommand[index]=onCommand; } //新增upStepCommand記錄上一步命令 public void clickOn(int index){ onCommand[index].exceute(); upStepCommand=onCommand[index]; } //新增upStepCommand記錄上一步命令 public void clickOff(int index){ offCommand[index].exceute(); upStepCommand=offCommand[index]; } public void toUpStepClick(){ System.out.println("---撤銷---"); upStepCommand.revoke(); } /** * 輸出每個按鈕的具體代表類 * @return */ @Override public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < onCommand.length; i++) { sb.append("[index : "+i+"] "); sb.append(onCommand[i].getClass().getName()); sb.append(" "); sb.append(offCommand[i].getClass().getName()); sb.append("\r\n"); } return sb.toString(); } }View Code
測試類新增撤銷測試
package com.commandPattern.testPattern; import com.commandPattern.command.off.LampOffCommand; import com.commandPattern.command.off.TvOffCommand; import com.commandPattern.command.on.LampOnCommand; import com.commandPattern.command.on.TvOnCommand; import com.commandPattern.control.RemoteControl; import com.commandPattern.entity.Lamp; import com.commandPattern.entity.Tv; /** * @program: test * @description: * @author: Mr.Yang * @create: 2018-12-08 17:48 **/ public class TestPattern { public static void main(String[] args) { RemoteControl remoteControl = new RemoteControl(); /** * 創建裝置到合適位置 */ Tv bedRoomTV = new Tv("卧室"); Tv drawiTV = new Tv("客廳"); Lamp bedRoomLamp = new Lamp("卧室"); Lamp drawiLamp = new Lamp("客廳"); /** * 創建所有命令操作對象 */ //卧室燈關閉對象 LampOffCommand bedLampOffCommand = new LampOffCommand(bedRoomLamp); //卧室燈打開對象 LampOnCommand bedLampOnCommand = new LampOnCommand(bedRoomLamp); //卧室TV關閉對象 TvOffCommand bedTvOffCommand = new TvOffCommand(bedRoomTV); //卧室TV打開對象 TvOnCommand bedTVcommand = new TvOnCommand(bedRoomTV); //客廳燈打開對象 LampOnCommand drawLampOnCommand = new LampOnCommand(drawiLamp); //客廳燈關閉對象 LampOffCommand drawLampOffCommand = new LampOffCommand(drawiLamp); //客廳TV關閉對象 TvOffCommand drawTVOffCommand = new TvOffCommand(drawiTV); //客廳TV打開對象 TvOnCommand drawTVOnCommand = new TvOnCommand(drawiTV); System.out.println("---------------------------------------------未賦值之前------------------------------------------------"); System.out.println(remoteControl); System.out.println("******************************************************************************************************"); /** * //將操作對象與卡槽一一對應 */ //賦值卧室燈打開與關閉 remoteControl.setCommond(0,bedLampOnCommand,bedLampOffCommand); //賦值卧室TV打開與關閉 remoteControl.setCommond(1,bedTVcommand,bedTvOffCommand); //賦值客廳燈打開與關閉 remoteControl.setCommond(2,drawLampOnCommand,drawLampOffCommand); //賦值客廳TV打開與關閉 remoteControl.setCommond(3,drawTVOnCommand,drawTVOffCommand); System.out.println("---------------------------------------------賦值之後------------------------------------------------"); System.out.println(remoteControl); System.out.println("******************************************************************************************************"); /** * 測試每一個按鈕 */ remoteControl.clickOn(0); remoteControl.clickOff(0); //撤銷一次 remoteControl.toUpStepClick(); System.out.println("\r\n"); //撤銷一次 remoteControl.toUpStepClick(); System.out.println("\r\n"); remoteControl.clickOn(1); remoteControl.clickOff(1); //撤銷一次 remoteControl.toUpStepClick(); System.out.println("\r\n"); remoteControl.clickOn(2); remoteControl.clickOff(2); //撤銷一次 remoteControl.toUpStepClick(); System.out.println("\r\n"); remoteControl.clickOn(3); remoteControl.clickOff(3); //撤銷一次 remoteControl.toUpStepClick(); System.out.println("\r\n"); } }View Code
修改之後的測試結果
---------------------------------------------未賦值之前------------------------------------------------ [index : 0] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 1] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 2] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 3] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand [index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand ****************************************************************************************************** ---------------------------------------------賦值之後------------------------------------------------ [index : 0] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand [index : 1] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand [index : 2] com.commandPattern.command.on.LampOnCommand com.commandPattern.command.off.LampOffCommand [index : 3] com.commandPattern.command.on.TvOnCommand com.commandPattern.command.off.TvOffCommand [index : 4] com.commandPattern.command.nullCommand.NullCommand com.commandPattern.command.nullCommand.NullCommand ****************************************************************************************************** 卧室_燈打開 卧室_燈關閉 ---撤銷--- 卧室_燈打開 ---撤銷--- 卧室_燈打開 卧室_電視打開 卧室_電視關閉 ---撤銷--- 卧室_電視打開 客廳_燈打開 客廳_燈關閉 ---撤銷--- 客廳_燈打開 客廳_電視打開 客廳_電視關閉 ---撤銷--- 客廳_電視打開View Code
項目組長阿飛:不錯,不錯,以後給你漲工資。