命令模式定義
命令模式將請(qǐng)求封裝成對(duì)象,以便使用不同的請(qǐng)求茫船、隊(duì)列或者日志來(lái)參數(shù)化其他對(duì)象愿棋,命令模式支持可撤銷的操作。
命令模式可以對(duì)發(fā)送者和接受者完全解耦诈嘿,發(fā)送者和接收者之間沒(méi)有直接的聯(lián)系堪旧,發(fā)送者只需要知道如何發(fā)送請(qǐng)求,不需要關(guān)心請(qǐng)求如何完成奖亚,這就是命令模式崎场,命令模式將方法的調(diào)用給封裝起來(lái)了。
命令模式結(jié)構(gòu)
image
說(shuō)明:上圖中的Command:抽象命令類遂蛀,ConcreteCommand:具體命令類谭跨,Invoker:調(diào)用者,Receiver:接受者,Client:客戶類螃宙。命令的模式本質(zhì)就在于將命令進(jìn)行封裝蛮瞄,將發(fā)出的命令測(cè)責(zé)任和執(zhí)行命令的責(zé)任分開,發(fā)送者只需要知道如何發(fā)送指令即可谆扎,不需要知道命令如何實(shí)現(xiàn)的挂捅,甚至執(zhí)行是否成功都不需要知道,命令模式將請(qǐng)求也變?yōu)橐粋€(gè)對(duì)象堂湖,它和其他對(duì)象一樣可以被存儲(chǔ)和傳遞闲先。
命令模式的實(shí)現(xiàn)
在這里,我們以電視機(jī)為例无蜂,電視劇是請(qǐng)求的接受者伺糠,遙控器是請(qǐng)求的發(fā)送者,遙控器上有一些按鈕斥季,不同的按鈕對(duì)應(yīng)不同的操作训桶,在這里遙控器需要執(zhí)行三個(gè)命令,打開電視酣倾,關(guān)閉電視舵揭,換臺(tái)。
類圖結(jié)構(gòu)如下
image
抽象命令接口
/**
* 命令接口躁锡,為所有的命令聲明一個(gè)接口
*@author lky
*@date 2018年1月19日
*/
public interface Command {
public void excute();
}
電視機(jī)類
/**
* 電視機(jī)類
*@author lky
*@date 2018年1月19日
*/
public class Telvision {
public void open(){
System.out.println("打開電視機(jī)....");
}
public void close(){
System.out.println("關(guān)閉電視機(jī)....");
}
public void changeChannel(){
System.out.println("切換電視機(jī)頻道....");
}
}
遙控器類
/**
* 遙控器類
*@author lky
*@date 2018年1月19日
*/
public class Controller {
private Command openTvCommand;
private Command closeTvCommand;
private Command changeTvCommand;
public Controller(Command openTvCommand, Command closeTvCommand,
Command changeTvCommand) {
super();
this.openTvCommand = openTvCommand;
this.closeTvCommand = closeTvCommand;
this.changeTvCommand = changeTvCommand;
}
public void open(){
openTvCommand.excute();
}
public void close(){
closeTvCommand.excute();
}
public void change(){
changeTvCommand.excute();
}
}
遙控器的打開按鈕類
/**
* 遙控器的打開電視按鈕
*@author lky
*@date 2018年1月19日
*/
public class OpenTvCommand implements Command{
private Telvision tv;
public OpenTvCommand() {
tv = new Telvision();
}
@Override
public void excute() {
tv.open();
}
}
遙控器的換臺(tái)按鈕
/**
* 遙控機(jī)換臺(tái)按鈕
*@author lky
*@date 2018年1月19日
*/
public class ChangeTvCommand implements Command{
private Telvision tv;
public ChangeTvCommand() {
tv = new Telvision();
}
@Override
public void excute() {
tv.changeChannel();
}
}
遙控器的關(guān)閉按鈕
public class CloseTvCommand implements Command{
private Telvision tv;
public CloseTvCommand() {
tv = new Telvision();
}
@Override
public void excute() {
tv.close();
}
}
客戶端
public class Client {
public static void main(String[] args) {
Command openCommand,closeCommand,changeCommand;
openCommand = new OpenTvCommand();
closeCommand = new CloseTvCommand();
changeCommand = new ChangeTvCommand();
Controller controller = new Controller(openCommand, closeCommand, changeCommand);
controller.open();
controller.change();
controller.close();
}
}
輸出結(jié)果
打開電視機(jī)....
切換電視機(jī)頻道....
關(guān)閉電視機(jī)....
為方便理解午绳,將代碼放在一起
[圖片上傳失敗...(image-3e5f5e-1519534651204)]
命令模式的優(yōu)缺點(diǎn)
- 降低了系統(tǒng)的耦合度
- 新的命令可以很容易的添加進(jìn)去
- 使用命令模式可能會(huì)導(dǎo)致某些系統(tǒng)有過(guò)多的具體命令類
命令模式的使用場(chǎng)景
- 系統(tǒng)需要請(qǐng)求調(diào)用者和請(qǐng)求接受者解耦,使得調(diào)用者和接收者不會(huì)直接交互
- 系統(tǒng)需要在不同的時(shí)間指定請(qǐng)求映之,將請(qǐng)求排隊(duì)和執(zhí)行請(qǐng)求
- 系統(tǒng)需要支持命令的插銷和恢復(fù)操作
- 系統(tǒng)需要將一組操作組合在一起
總結(jié)
- 命令模式的本質(zhì)是將命令對(duì)象進(jìn)行封裝打包拦焚,將發(fā)出的命令的責(zé)任和執(zhí)行命令的責(zé)任進(jìn)行分割開。
- 命令模式中發(fā)送者只需要知道如何發(fā)送命令惕医,無(wú)需關(guān)心命令執(zhí)行的具體過(guò)程耕漱。
- 在發(fā)送者和接受者兩者之間是通過(guò)命令對(duì)象進(jìn)行溝通的,請(qǐng)求命令本身就當(dāng)做一個(gè)對(duì)象在兩者之間進(jìn)行傳遞抬伺,他封裝了接受者和一組動(dòng)作螟够。
- 命令模式支持撤銷操作。
- 命令模式隊(duì)列請(qǐng)求和日志請(qǐng)求峡钓。