在前面的章節中,咱們介紹了單例模式,它是建立型模式的一員。今天咱們來介紹一下命令模式,它是行爲型模式的一員。java
首先,讓咱們來思考下面的問題:ide
話說有一家遙控器公司,他想製做一款很牛逼的遙控器。這個遙控器能夠控制家裏全部的電器,爲了簡單一點,假設全部的用戶家裏只有電視機和電燈兩種電器。那麼若是是你,你會怎麼實現這個遙控器呢?
因爲電視機和電燈是兩個不一樣的廠商生產的產品,因此他們的打開方式是不同的。首先讓咱們來看一看這兩個類的定義:測試
Television.java:this
public class Television { public void open() { System.out.println("打開電視"); } public void close() { System.out.println("關閉電視"); } }
ElectricLight.java:spa
public class ElectricLight { public void on() { System.out.println("打開電燈"); } public void off() { System.out.println("關閉電燈"); } }
讓咱們來看下下面的設計:設計
RemoteControl.java:3d
public class RemoteControl { private String product; public void setProduct(String product) { this.product = product; } public void execute() { switch (product) { case "Television": new Television().open(); break; case "ElectricLight": new ElectricLight().on(); break; default: } } }
這個遙控器太棒了,我能夠用它來控制家裏的電視機和電燈,不再用處處翻找遙控器了。要是它還能夠控制洗衣機那就更棒了。那麼若是再在遙控器裏添加一個洗衣機須要怎麼作,哦,太糟糕了,我還須要把遙控器拆開,而後把洗衣機的命令添加進去,好痛苦有麼有,那麼有麼有一種設計能夠不對遙控器進行更改,就能夠添加其餘的家電呢。這個時候命令模式就能夠發揮它的做用了。code
定義:將請求封裝成對象,從而可使用不一樣的請求將客戶參數化,使得請求發送者和請求接受者之間互相隔離。對象
類圖:blog
上面涉及到的角色有4個:
首先,定義一個抽象命令類:
Command.java:
public interface Command { void execute(); }
而後,實現抽象命令類:
TelevisionCommand.java:
public class TelevisionCommand implements Command { private Television television = new Television(); @Override public void execute() { television.open(); } }
ElectricLightCommand.java:
public class ElectricLightCommand implements Command { private ElectricLight electricLight = new ElectricLight(); @Override public void execute() { electricLight.on(); } }
而後,實現一個遙控器:
RemoteControl.java:
public class RemoteControl { private Command command; public void execute() { command.execute(); } public void initCommand(Command command) { this.command = command; } }
測試類:
Custom.java:
public class Custom { public static void main(String ...args) { RemoteControl remoteControl = new RemoteControl(); remoteControl.initCommand(new TelevisionCommand()); remoteControl.execute(); remoteControl.initCommand(new ElectricLightCommand()); remoteControl.execute(); } }