定義
將“請求”封裝成對象,以便使用不同的請求宜狐、隊(duì)列或者日志類參數(shù)化其他對象势告。命令模式也可以支持撤銷的操作。
要點(diǎn)
1抚恒、命令模式將發(fā)出的請求和執(zhí)行請求的對象進(jìn)行解耦咱台。
2、在被解耦的兩者之間是通過命令對象進(jìn)行溝通的俭驮,命令對象封裝了接收者的一個(gè)或一組動作
3回溺、調(diào)用者通過命令對象的execute()發(fā)出請求,這會使得接收者的動作被調(diào)用混萝。
4遗遵、調(diào)用者可以接受命令當(dāng)做參數(shù),甚至在運(yùn)行時(shí)動態(tài)的進(jìn)行
用途
1逸嘀、命令模式將發(fā)出請求的對象和執(zhí)行請求的對象進(jìn)行解耦
2车要、用于隊(duì)列請求,命令對象和一般對象一樣可以被傳來傳去崭倘,只要實(shí)現(xiàn)統(tǒng)一的接口方法翼岁,可以被任意調(diào)用
3、用于日志請求司光,將所有動作記錄在日志中琅坡,以便系統(tǒng)死機(jī)后能夠重新調(diào)用來恢復(fù)
參與對象
1、調(diào)用者:用來發(fā)送請求的對象
2飘庄、接收者:接受請求實(shí)際執(zhí)行一組動作的對象
3脑蠕、命令對象:在調(diào)用者和接收者間充當(dāng)解耦的角色,將調(diào)用者和接收者結(jié)合起來
舉例應(yīng)用
有一個(gè)遙控器跪削,還有電燈谴仙、電風(fēng)扇、空調(diào)等電器碾盐,要實(shí)現(xiàn)遙控器可以隨意切換執(zhí)行對這些電器的遙控晃跺。
進(jìn)行抽象
1、調(diào)用者:遙控器
2毫玖、接收者:電器
3掀虎、命令對象
類圖
具體實(shí)現(xiàn)
電器:
Light:
public class Light {
private String location;
public Light(String location) {
this.location = location;
}
public void on() {
System.out.println(location + "電燈打開");
}
public void off() {
System.out.println(location + "電燈關(guān)閉");
}
}
Fridge:
public class Fridge {
private String location;
public Fridge(String location) {
this.location = location;
}
public void on() {
System.out.println(location + "冰箱打開");
}
public void off() {
System.out.println(location + "冰箱關(guān)閉");
}
}
CellingFan:
public class CellingFan {
private String location;
public CellingFan(String location) {
this.location = location;
}
public void high(){
System.out.println(location +"的電風(fēng)扇開啟高檔");
}
public void medium(){
System.out.println(location +"的電風(fēng)扇開啟中檔");
}
public void low(){
System.out.println(location +"的電風(fēng)扇開啟低擋");
}
public void off(){
System.out.println(location +"的電風(fēng)扇關(guān)閉");
}
}
Command(命令對象接口)
public interface Command {
void execute();
}
具體命令對象:
LightOffCommand:
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
}
LightOnCommand:
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
FridgeOnCommand:
public class FridgeOnCommand implements Command {
private Fridge fridge;
public FridgeOnCommand(Fridge fridge) {
this.fridge = fridge;
}
@Override
public void execute() {
fridge.on();
}
}
FridgeOffCommand:
public class FridgeOffCommand implements Command {
private Fridge fridge;
public FridgeOffCommand(Fridge fridge) {
this.fridge = fridge;
}
@Override
public void execute() {
fridge.off();
}
}
CellingFanOnCommand:
public class CellingFanOnCommand implements Command {
private CellingFan cellingFan;
public CellingFanOnCommand(CellingFan cellingFan) {
this.cellingFan = cellingFan;
}
@Override
public void execute() {
cellingFan.high();
}
}
CellingFanOffCommand:
public class CellingFanOffCommand implements Command{
private CellingFan cellingFan;
public CellingFanOffCommand(CellingFan cellingFan) {
this.cellingFan = cellingFan;
}
@Override
public void execute() {
cellingFan.off();
}
}
RemoteControl(遙控器):
public class RemoteControl {
private Command onCommand;
private Command offCommand;
public void setOnCommand(Command onCommand) {
this.onCommand = onCommand;
}
public void setOffCommand(Command offCommand) {
this.offCommand = offCommand;
}
public void on(){
onCommand.execute();
}
public void off(){
offCommand.execute();
}
public static void main(String[] args) {
RemoteControl rc = new RemoteControl();
Light light = new Light("客廳");
LightOnCommand lightOnCommand = new LightOnCommand(light);
LightOffCommand lightOffCommand = new LightOffCommand(light);
rc.setOffCommand(lightOffCommand);
rc.setOnCommand(lightOnCommand);
rc.on();
rc.off();
}
}
---
客廳電燈打開
客廳電燈關(guān)閉
如果直接使用Light凌盯、Fridge、CellingFan等直接命令執(zhí)行者放在RemoteControl中烹玉,可以使用if...else...
來實(shí)現(xiàn)驰怎,但是增加新的電器,那么就要修改RemoteControl代碼
而通過實(shí)現(xiàn)Command接口的命令對象二打,可以進(jìn)行完美解耦县忌。
總結(jié):
當(dāng)需要將發(fā)出請求的對象和執(zhí)行請求的對象進(jìn)行解耦的時(shí)候,則可以用到命令模式继效。