命令模式是把命令的發(fā)出和命令的執(zhí)行進行分開捻激,每個命令都是一個操作,請求方把命令發(fā)出前计,需要執(zhí)行某個動作胞谭,接受命令的一方接到命令進行執(zhí)行。命令模式把發(fā)送和接受分開男杈,使得請求方不知道接收方的接口丈屹。這樣做的有點是:1、可以增加新的命令;2旺垒、接收方可以決定是否要執(zhí)行彩库;3、日益實現(xiàn)執(zhí)行隊列先蒋;4骇钦、日益實現(xiàn) Undo 和 Redo 操作。
接下來看下具體的 UML 的類圖
Client
:確定具體的命令和接受者竞漾;
Command
:抽象命令接口眯搭,一般是接口類或者抽象類
ConcreteCommand
:具體的命令執(zhí)行,調(diào)用接受者
Invoker
:請求者业岁,把命令封裝進行請求鳞仙,調(diào)用 action 方法
Receiver
:接受者,被具體的命令調(diào)用笔时,一般任何類都可以擔當
紅色框里請求者和接受者沒有一毛錢的關系
有了上述的角色繁扎,進行一個基本的命令模式的代碼編寫
首先把命令接口編寫出來,這里只有一個執(zhí)行方法
public interface Command {
public void execute();
}
具體命令需要接受者糊闽,那么先把接受者編寫出
public class Receiver {
public void action(){
System.out.println("命令執(zhí)行完畢梳玫,已經(jīng)收到");
}
}
再把具體的命令編寫出
public class ConcreteCommand implements Command{
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver=receiver;
}
@Override
public void execute() {
System.out.println("開始執(zhí)行具體命令了");
receiver.action();
}
}
接下來把請求者Invoker 編寫出,他主要負責調(diào)用 Command
public class Invoker {
Command cammand;
public Invoker(Command cammand) {
this.cammand=cammand;
}
public void action(){
cammand.execute();
}
}
最后來個 Client 來測試測試
public class Client {
public static void main(String[] args) {
Receiver receiver=new Receiver();
Command command=new ConcreteCommand(receiver);
Invoker invoker=new Invoker(command);
invoker.action();
}
}
/** Result----
開始執(zhí)行具體命令了
命令執(zhí)行完畢右犹,已經(jīng)收到
*/
以上是模擬代碼提澎,來個實際情況,比如小王看電視念链,小王相當于客戶端盼忌,電視相當于接收者,遙控器相當于請求者掂墓,遙控器上有若干的命令谦纱,開機,關機君编,換頻道跨嘉,調(diào)節(jié)聲音等等。
下面就編寫這個實現(xiàn)代碼吃嘿。
先把電視編寫出來
public class TV {
public void on(){
System.out.println("打開電視");
}
public void off(){
System.out.println("關閉電視");
}
public void turnChannel(){
System.out.println("換頻道");
}
public void volumnUp(){
System.out.println("提高聲音");
}
}
電視機本身的接受方法以及處理
有了電視實際接受者祠乃,現(xiàn)在把抽象命令編寫出
public abstract class TVCommand {
TV tv;
public TVCommand(TV tv) {
this.tv=tv;
}
public abstract void execute();
}
這里使用抽象類,里面的 execute 抽象方法給子類來做兑燥,下面看看各個子類的實現(xiàn)
public class OnCommand extends TVCommand{
public OnCommand(TV tv) {
super(tv);
}
@Override
public void execute() {
System.out.println("打開電視命令");
tv.on();
}
}
public class turnChannelCommand extends TVCommand{
public turnChannelCommand(TV tv) {
super(tv);
}
@Override
public void execute() {
System.out.println("改變電視頻道電視命令");
tv.turnChannel();
}
}
public class volumnUpCommand extends TVCommand{
public volumnUpCommand(TV tv) {
super(tv);
}
@Override
public void execute() {
System.out.println("調(diào)高音量命令");
tv.volumnUp();
}
}
public class OffCommand extends TVCommand{
public OffCommand(TV tv) {
super(tv);
}
@Override
public void execute() {
System.out.println("關閉電視命令");
tv.off();
}
}
此處有開啟亮瓷、換頻道、調(diào)節(jié)音量降瞳、關閉四個具體的命令嘱支,并且對 execute 方法進行具體實現(xiàn)。
下面把遙控器類給構(gòu)造出來,相當于發(fā)送請求
public class RemoteControl {
private TVCommand onCommand;
private TVCommand offCommand;
private TVCommand turnChannelCommand;
private TVCommand volumnUpCommand;
public RemoteControl() {
}
public void on(){
onCommand.execute();
}
public void off(){
offCommand.execute();
}
public void turnChannel(){
turnChannelCommand.execute();
}
public void volumnUp(){
volumnUpCommand.execute();
}
public RemoteControl setCommand(TVCommand command){
if(command instanceof OnCommand){
this.onCommand=command;
}
if(command instanceof OffCommand){
this.offCommand=command;
}
if(command instanceof turnChannelCommand){
this.turnChannelCommand=command;
}
if(command instanceof volumnUpCommand){
this.volumnUpCommand=command;
}
return this;
}
}
遙控器也有開除师、關赢织、換頻道、調(diào)聲音這些方法馍盟,這些方法相當于把具體命令實現(xiàn)類進行歸納匯總于置,客戶端小王借助遙控器就可以發(fā)號施令。來看下小王這個類
public class Xiaowang {
public static void main(String[] args) {
TV tv=new TV();
TVCommand on=new OnCommand(tv);
TVCommand off=new OffCommand(tv);
TVCommand turnChannel=new turnChannelCommand(tv);
TVCommand volumnUp=new volumnUpCommand(tv);
RemoteControl control=new RemoteControl();
control.setCommand(off)
.setCommand(on)
.setCommand(turnChannel)
.setCommand(volumnUp);
control.on();
control.turnChannel();
control.volumnUp();
control.off();
}
}
/** ---- result ----
打開電視命令
打開電視
改變電視頻道電視命令
換頻道
調(diào)高音量命令
提高聲音
關閉電視命令
關閉電視
*/