設計模式-命令模式

命令模式是把命令的發(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)高音量命令
提高聲音
關閉電視命令
關閉電視
*/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贞岭,一起剝皮案震驚了整個濱河市八毯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瞄桨,老刑警劉巖话速,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芯侥,居然都是意外死亡泊交,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門柱查,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廓俭,“玉大人,你說我怎么就攤上這事唉工⊙衅梗” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵淋硝,是天一觀的道長雹熬。 經(jīng)常有香客問我,道長谣膳,這世上最難降的妖魔是什么竿报? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮继谚,結(jié)果婚禮上烈菌,老公的妹妹穿的比我還像新娘。我一直安慰自己犬庇,他們只是感情好僧界,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布侨嘀。 她就那樣靜靜地躺著臭挽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咬腕。 梳的紋絲不亂的頭發(fā)上欢峰,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音,去河邊找鬼纽帖。 笑死宠漩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的懊直。 我是一名探鬼主播扒吁,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼室囊!你這毒婦竟也來了雕崩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤融撞,失蹤者是張志新(化名)和其女友劉穎盼铁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尝偎,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡饶火,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了致扯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肤寝。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖抖僵,靈堂內(nèi)的尸體忽然破棺而出醒陆,到底是詐尸還是另有隱情,我是刑警寧澤裆针,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布刨摩,位于F島的核電站,受9級特大地震影響世吨,放射性物質(zhì)發(fā)生泄漏澡刹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一耘婚、第九天 我趴在偏房一處隱蔽的房頂上張望罢浇。 院中可真熱鬧,春花似錦沐祷、人聲如沸嚷闭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胞锰。三九已至,卻和暖如春兢榨,著一層夾襖步出監(jiān)牢的瞬間嗅榕,已是汗流浹背顺饮。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凌那,地道東北人兼雄。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像帽蝶,于是被迫代替她去往敵國和親赦肋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 目錄 本文的結(jié)構(gòu)如下: 什么是命令模式 為什么要用該模式 模式的結(jié)構(gòu) 代碼示例 優(yōu)點和缺點 適用環(huán)境 模式應用 總...
    w1992wishes閱讀 1,102評論 2 9
  • 場景 在飯店里吃飯經(jīng)常會出現(xiàn)上餐錯誤的問題励稳,比如上菜順序不對或上菜上錯桌的情況 問題來了這種情況在編程中就是常說的...
    皆為序幕_閱讀 394評論 0 1
  • 命令模式定義 命令模式將請求封裝成對象金砍,以便使用不同的請求、隊列或者日志來參數(shù)化其他對象麦锯,命令模式支持可撤銷的操作...
    Waldeinsamkeit4閱讀 330評論 0 1
  • 命令模式(Command) 在軟件開發(fā)系統(tǒng)中恕稠,常常出現(xiàn)“方法的請求者”與“方法的實現(xiàn)者”之間存在緊密的耦合關系。這...
    Acton_zhang閱讀 256評論 0 1
  • 她是一個農(nóng)村家庭的孩子扶欣,姐弟三人鹅巍,父親有修牙的技術(shù),料祠,父親是個老好人骆捧,母親是持家的能手,有主見髓绽,性格強勢敛苇,...
    王耀億js閱讀 170評論 0 0