又是新的一周了,今天股市基金兩頭紅,心情高興不扯淡,直接代碼就是干。
命令模式是一個簡單且實(shí)用的設(shè)計模式;我們先看看定義:
命令模式是一個高內(nèi)聚的模式,其定義為:Encapsulate a request as an object,thereby
letting you parameterize clients with different requests,queue or log requests,and support undoable
operations.(將一個請求封裝成一個對象,從而讓你使用不同的請求把客戶端參數(shù)化,對請
求排隊或者記錄請求日志,可以提供命令的撤銷和恢復(fù)功能。)
官方說的很抽象難理解;所謂命令,就要有命令發(fā)布者,接收者,具體命令;我們試著寫個Demo;
例如有這么一個需求:
一個外包公司接了一個活,客戶以文檔形式提了一些需求,價格什么的都談好了;公司內(nèi)部研發(fā)團(tuán)隊也是比較健全的,有UI組有產(chǎn)品組有研發(fā)組;日后的協(xié)作中客戶會經(jīng)常變更需求;這個時候就有個溝通過程;我們現(xiàn)在用程序來模擬一下這個場景;
接收者是具體的項目組,比如修改個UI那就是UI組,添加個需求那就是需求組,我們來定義一下這個接收者的抽象:
package com.ldl.commonmode;
/**
* @author deling 2017年11月6日 定義命令的接收者具體由其子類接 收*/
public abstract class Group {
// 找到這個組
public abstract void find();
// 添加需求
public abstract void add();
// 刪除需求
public abstract void delete();
// 修改需求
public abstract void change();
// 給出一個具體修改后的計劃
public abstract void plan();
}
我們具體實(shí)現(xiàn)一個:
package com.ldl.commonmode;
/**
* @author deling 2017年11月6日
*/
class Products extends Group {
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#find()
*/
@Override
public void find() {
System.out.println("找到Products組");
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#add()
*/
@Override
public void add() {
// TODO Auto-generated method stub
System.out.println("讓Products組添加一個需求");
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#delete()
*/
@Override
public void delete() {
// TODO Auto-generated method stub
System.out.println("讓Products組刪除一個需求");
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#change()
*/
@Override
public void change() {
// TODO Auto-generated method stub
System.out.println("讓Products組修改一個需求");
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#plan()
*/
@Override
public void plan() {
// TODO Auto-generated method stub
System.out.println("讓Products組返回一個改變后的計劃書");
}
}
這個是產(chǎn)品組:
下面我們再具體定義一個Ui組和業(yè)務(wù)實(shí)現(xiàn)組:
package com.ldl.commonmode;
/**
* @author deling 2017年11月6日
*/
public class UiGroup extends Group {
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#find()
*/
@Override
public void find() {
System.out.println("找到Ui組");
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#add()
*/
@Override
public void add() {
System.out.println("讓Ui組刪除一個界面");
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#delete()
*/
@Override
public void delete() {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#change()
*/
@Override
public void change() {
// TODO Auto-generated method stub
System.out.println("讓Ui組修改一個界面");
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Group#plan()
*/
@Override
public void plan() {
// TODO Auto-generated method stub
System.out.println("讓Ui返回給一個具體修改后的計劃");
}
}
好了Code組同上,我們怎么調(diào)用呢這三個組相互協(xié)調(diào),總得有個調(diào)度員吧;我了我們定義個Invoker類作為調(diào)度員:
package com.ldl.commonmode;
/**
* @author deling 2017年11月6日定義一個接頭人跟客戶對接接收客戶命令 并且執(zhí)行 */
public class Invoker {
private Command command;
public Command getCommand() {
return command;
}
public void setCommand(Command command) {
this.command = command;
}
public void action() {
this.command.execute();
}
}
測試一下:
package com.ldl.commonmode;
/* * @author deling 2017年11月6日定義一個接頭人跟客戶對接接收客戶命 令并且執(zhí)行
*/
public class Invoker {
private Command command;
public Command getCommand() {
return command;
}
public void setCommand(Command command) {
this.command = command;
}
public void action() {
this.command.execute();
}
}

效果還不錯哦,
這就是一種命令模式的應(yīng)用;Group及其子類是具體命令接收執(zhí)行者,Command以及其子類是具體的命令;命令發(fā)布協(xié)調(diào)調(diào)用是Invoker 來調(diào)度;具體發(fā)布什么命令可以繼續(xù)擴(kuò)展;我們也可以在發(fā)布命令時候指定接收者;例如:
package com.ldl.commonmode;
/**
* @author deling 2017年11月6日
*/
public class GloabCommand extends Command {
private Group gloabGroup;
public GloabCommand(Group gloabGroup) {
super();
this.gloabGroup = gloabGroup;
}
/*
* (non-Javadoc)
*
* @see com.ldl.commonmode.Command#execute()
*/
@Override
public void execute() {
// TODO Auto-generated method stub
this.gloabGroup.find();
}}
我們定義一個命令在構(gòu)造方法里傳進(jìn)去由誰來接收執(zhí)行;測試下
Command gloabCommand=new GloabCommand(new CodeGroup());
invoker.setCommand(gloabCommand);
invoker.action();

總結(jié)一下:
命令模式的缺點(diǎn):
命令過多時候會造成命令膨脹;
優(yōu)點(diǎn):
類之間解耦,調(diào)用者角色與接收者角色之間沒有任何依賴關(guān)系,調(diào)用者實(shí)現(xiàn)功能時只需調(diào)用Command
抽象類的execute方法就可以;
可擴(kuò)展性:子命令可以很容易擴(kuò)展;而調(diào)用者Invoker和高層次的模塊Client不產(chǎn)生嚴(yán)
重的代碼耦合。
對命令的撤銷我們可以這么做;在接受者里抽取一個模板方法;具體命令里調(diào)用這個接收者的回滾的方法;最后我們附上一個通用類圖:
