英雄聯(lián)盟中的設(shè)計(jì)模式-命令模式

將“請(qǐng)求”封裝成對(duì)象,以便使用不同的請(qǐng)求、隊(duì)列、或者日志來(lái)參數(shù)化其他對(duì)象。命令模式也支持可撤銷的操作。

每一位召喚師都有QWER4個(gè)技能,當(dāng)我們按下鍵盤上(或其他外設(shè))的Q按鈕后,我們操控的召喚師就會(huì)釋放Q技能進(jìn)行攻擊。整個(gè)過(guò)程可以使用命令模式來(lái)描述。命令模式可以將請(qǐng)求者與接收者之間解耦。

命令模式是在特定接收者上綁定一組動(dòng)作來(lái)封裝成一個(gè)請(qǐng)求(命令對(duì)象),而這個(gè)請(qǐng)求只暴露出一個(gè)execute方法,當(dāng)此方法被調(diào)用的時(shí)候,接收者就會(huì)負(fù)責(zé)進(jìn)行這些動(dòng)作。而對(duì)于外面來(lái)看,其他對(duì)象不知道究竟是哪個(gè)接收者進(jìn)行了哪些動(dòng)作,只知道如果調(diào)用了execute方法,請(qǐng)求的目的就能達(dá)到。

命令模式還能實(shí)現(xiàn)撤銷操作,也比較簡(jiǎn)單,只需讓接收者實(shí)現(xiàn)命令的相反操作即可。

1. 簡(jiǎn)單的命令模式
@protocol Command <NSObject>
- (void)execute;    // 執(zhí)行命令
- (void)undo;       // 撤銷命令
@end

@implementation Skill_Q {
    Summoner *_summoner;
}
- (instancetype)initWithSummoner:(Summoner *)summoner {
    self = [super init];
    if (self) {
        _summoner = summoner;
    }
    return self;
}
- (void)execute {
   [_summoner touchSkillWithNumber:@"Q"];
}
- (void)undo {
    [_summoner cancelSkillWithNumber:@"Q"];
}
@end
外設(shè)類圖
@interface OuterDevice : NSObject
@property (nonatomic, strong, readonly) NSMutableDictionary *commandMap;
- (void)buttonAddCommand:(id<Command>)command number:(NSString *)number;//給外設(shè)按鈕增加命令
- (void)pressedButtonWithNumber:(NSString *)number;//按下按鈕
- (void)undoPressedButtonWithNumber:(NSString *)number;//撤銷按下按鈕操作
@end

@implementation OuterDevice

- (instancetype)init {
    self = [super init];
    if (self) {
        _commandMap = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (void)buttonAddCommand:(id<Command>)command number:(NSString *)number {
    [_commandMap setObject:command forKey:number];
}
- (void)pressedButtonWithNumber:(NSString *)number {
    id<Command> command = [_commandMap objectForKey:number];
    [command execute];
}
- (void)undoPressedButtonWithNumber:(NSString *)number {
    id<Command> command = [_commandMap objectForKey:number];
    [command undo];
}
@end

可能你覺得接收者不一定要存在,可以讓命令對(duì)象直接實(shí)現(xiàn)execute方法。但是,這樣的做法使得調(diào)用者與接收者之間的耦合程度增加,而且還不能將接收者當(dāng)作參數(shù)傳遞給命令。所以,還是將命令對(duì)象設(shè)計(jì)的簡(jiǎn)單、傻瓜點(diǎn)更合適。
具體代碼傳送門

2. 隊(duì)列請(qǐng)求

命令模式可以將一個(gè)接收者和一組動(dòng)作打包,供不同的線程調(diào)用,我們可以利用這個(gè)特性來(lái)創(chuàng)建隊(duì)列請(qǐng)求操作。比如在隊(duì)列的一端添加各式各樣的命令對(duì)象,而線程從隊(duì)列的另一端中取出命令對(duì)象,調(diào)用其execute方法便能完成相關(guān)任務(wù)。線程不必知道具體的命令是什么,這樣就達(dá)到了解耦。

3. 日志

我們還可以利用命令模式將用戶的動(dòng)作記錄到日志中,通過(guò)序列化把命令對(duì)象存儲(chǔ)到磁盤中,一旦系統(tǒng)死機(jī),重啟后我們就可以將命令對(duì)象重新加載并執(zhí)行,這樣就使系統(tǒng)恢復(fù)到了上一次死機(jī)前的那一刻。

傾情告白:為交互對(duì)象之間的松耦合設(shè)計(jì)而努力!

關(guān)注微信公眾號(hào)CodingArtist,可以第一時(shí)間得到文章更新通知! _

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評(píng)論 19 139
  • 目錄 本文的結(jié)構(gòu)如下: 什么是命令模式 為什么要用該模式 模式的結(jié)構(gòu) 代碼示例 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 模式應(yīng)用 總...
    w1992wishes閱讀 1,249評(píng)論 2 9
  • 3.5 隊(duì)列請(qǐng)求## 所謂隊(duì)列請(qǐng)求,就是對(duì)命令對(duì)象進(jìn)行排隊(duì),組成工作隊(duì)列,然后依次取出命令對(duì)象來(lái)執(zhí)行。多用多線程或...
    七寸知架構(gòu)閱讀 2,142評(píng)論 4 53
  • 1 場(chǎng)景問(wèn)題# 1.1 如何開機(jī)## 估計(jì)有些朋友看到這個(gè)標(biāo)題會(huì)非常奇怪,電腦裝配好了,如何開機(jī)?不就是按下啟動(dòng)按...
    七寸知架構(gòu)閱讀 2,897評(píng)論 1 59
  • 意圖 簡(jiǎn)單的說(shuō),命令模式可將“動(dòng)作的請(qǐng)求者”從“動(dòng)作的執(zhí)行者”對(duì)象中解耦。 將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用...
    tomas家的小撥浪鼓閱讀 13,444評(píng)論 4 5

友情鏈接更多精彩內(nèi)容