類圖結構
- Receiver接受者角色:該角色就是干活的角色搀庶,命令傳遞到這里是應該被執(zhí)行的
- Command命令角色:需要執(zhí)行的所有命令都在這里聲明
- Invoker調用者角色:接收到命令鞍时,并執(zhí)行命令
//通用Receiver類
public abstract class Receiver {
public abstract void doSomething();
}
//具體Receiver類
public class ConcreteReciver1 extends Receiver{
//每個接收者都必須處理一定的業(yè)務邏輯
public void doSomething(){ }
}
public class ConcreteReciver2 extends Receiver{
//每個接收者都必須處理一定的業(yè)務邏輯
public void doSomething(){ }
}
//抽象Command類
public abstract class Command {
public abstract void execute();
}
//具體的Command類
public class ConcreteCommand1 extends Command {
//對哪個Receiver類進行命令處理
private Receiver receiver;
//構造函數(shù)傳遞接收者
public ConcreteCommand1(Receiver _receiver){
this.receiver = _receiver;
}
//必須實現(xiàn)一個命令
public void execute() {
//業(yè)務處理
this.receiver.doSomething();
}
}
public class ConcreteCommand2 extends Command {
//哪個Receiver類進行命令處理
private Receiver receiver;
//構造函數(shù)傳遞接收者
public ConcreteCommand2(Receiver _receiver){
this.receiver = _receiver;
}
//必須實現(xiàn)一個命令
public void execute() {
//業(yè)務處理
this.receiver.doSomething();
}
}
//調用者Invoker類
public class Invoker {
private Command command;
public void setCommand(Command _command){
this.command = _command;
}
public void action() {
this.command.execute();
}
}
//場景類
public class Client {
public static void main(String[] args){
Invoker invoker = new Invoker();
Receiver receiver = new ConcreteReceiver1();
Command command = new ConcreteCommand1(receiver);
invoker.setCommand(command);
invoker.action();
}
}
實例2
|現(xiàn)在比較火的小米手機,可以當作遙控器控制多種不同的家電,手機發(fā)送命令妓布,不同的電器接收到后執(zhí)行酌伊。
- Command類
public interface Command {
public void execute();
public void undo();
}
- 開燈命令
public class LightOnCommand implements Command {
private Light light;
LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
public void undo() {
light.off();
}
}
- 開電視命令
public class TVOnCommand implements Command {
private TV tv;
public TVOnCommand(TV tv) {
this.tv = tv;
}
public void execute() {
tv.on();
}
public void undo() {
tv.off();
}
}
- 家用電器接口類
public interface HouseholdAppliances {
public void on();
public void off();
}
- 電視類
public class TV implements HouseholdAppliances {
public void on() {
System.out.println("the TV on");
}
public void off() {
System.out.println("the TV off");
}
}
- 電燈類
public class Light implements HouseholdAppliances{
public void on() {
System.out.println("the light on");
}
public void off() {
System.out.println("the light off");
}
}
- 手機控制器類
public class MiPhone {
ArrayList commands;
public MiPhone() {
commands = new ArrayList();
}
public void setCommand(Command command) {
commands.add(command);
}
public void onButtonWasPushed(int slot) {
((Command)commands.get(slot-1)).execute();
}
public static void main(String[] args) {
MiPhone miPhone = new MiPhone();
//創(chuàng)建電器
Light light = new Light();
TV tv = new TV();
//創(chuàng)建命令
LightOnCommand lightOnCommand = new LightOnCommand(light);
TVOnCommand tvOnCommand = new TVOnCommand(tv);
//給小米手機設置命令
//設置第一個按鈕為開燈
miPhone.setCommand(lightOnCommand);
//設置第二個按鈕為開電視
miPhone.setCommand(tvOnCommand);
//開燈
miPhone.onButtonWasPushed(1);
//開電視
miPhone.onButtonWasPushed(2);
}
}
-
運行結果
應用
優(yōu)點
- 類間解耦:調用者角色與接收者角色之間沒有任何依賴關系舌厨,調用者實現(xiàn)功能時只需調用Command 抽象類的execute方法就可以浴鸿,不需要了解到底是哪個接收者執(zhí)行井氢。
- 可擴展性:Command的子類可以非常容易地擴展,而調用者Invoker和高層次的模塊Client不產生嚴 重的代碼耦合岳链。
- 命令模式結合其他模式會更優(yōu)秀:命令模式可以結合責任鏈模式花竞,實現(xiàn)命令族解析任務;結合模板方法模式掸哑,則可以減少 Command子類的膨脹問題
缺點
- 命令模式也是有缺點的约急,請看Command的子類:如果有N個命令,問題就出來 了举户,Command的子類就可不是幾個烤宙,而是N個,這個類膨脹得非常大俭嘁,這個就需要讀者在項 目中慎重考慮使用躺枕。