iOS必備設(shè)計(jì)模式-命令模式

命令模式就是將行為參數(shù)化,降低代碼重合度的
項(xiàng)目使用的場(chǎng)景比如:微博的點(diǎn)贊、評(píng)論和轉(zhuǎn)發(fā)

1、定義:

(1)將一個(gè)請(qǐng)求封裝成為一個(gè)對(duì)象,從而讓用戶使用不同的請(qǐng)求將客戶端參數(shù)化
(2)對(duì)請(qǐng)求排隊(duì)或者紀(jì)錄請(qǐng)求日志,以及支持撤銷操作

2、命令模式-應(yīng)用場(chǎng)景?

當(dāng)需要將方法調(diào)用包裝成一個(gè)對(duì)象,以延時(shí)方法調(diào)用,或者讓其他組件在對(duì)其內(nèi)部實(shí)現(xiàn)細(xì)節(jié)不了解的情況下進(jìn)行調(diào)用的時(shí)候可以使用命令模式
場(chǎng)景一:應(yīng)用程序支持撤銷和恢復(fù)
場(chǎng)景二:記錄請(qǐng)求日志,當(dāng)系統(tǒng)故障這些命令可以重新被執(zhí)行
場(chǎng)景三:想用對(duì)象參數(shù)化一個(gè)動(dòng)作以執(zhí)行操作,并且用不同命令對(duì)象來(lái)替換回調(diào)函數(shù)

3、命令模式-角色劃分?——>有很多變種(演示變種)

行為設(shè)計(jì)模式中一種

角色一:接收者(Receiver作用:負(fù)責(zé)具體的功能實(shí)現(xiàn)->具體實(shí)現(xiàn)細(xì)節(jié))
角色二:命令接口(協(xié)議)(Command:命令抽象)
角色三:具體的命令(ConcreteCmmand:具體的命令,作用:負(fù)責(zé)調(diào)用接收者邏輯方法,行為方法)
角色四:請(qǐng)求者角色(Invoker:調(diào)用執(zhí)行命令)
角色五:客戶端

原文

備注:原文的demo與實(shí)例的方式不一樣

實(shí)例:


image.png

命令基礎(chǔ)類

#import <Foundation/Foundation.h>

@class Command;
typedef void(^CommandCompletionCallBack)(Command* cmd);


@interface Command : NSObject
@property (nonatomic, copy, readwrite) CommandCompletionCallBack completion;

/**
 執(zhí)行
 */
- (void)execute;

/**
 撤銷
 */
- (void)cancle;

/**
 完成
 */
- (void)done;

@end
#import "Command.h"
#import "CommandManager.h"

@implementation Command

/**
 執(zhí)行
 */
- (void)execute {
    // override to subclass
    // 在繼承的子類中,執(zhí)行對(duì)應(yīng)的命令業(yè)務(wù),最后要調(diào)用done的方法
    [self done];
}

/**
 撤銷
 */
- (void)cancle {
    self.completion = nil;
}

/**
 完成
 */
- (void)done {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (_completion) {
            _completion(self);
        }
        // 釋放
        self.completion = nil;
        // 移除
        [[[CommandManager shareInstance] arrayCommands] removeObject:self];
    });
}

@end

命令管理者

#import <Foundation/Foundation.h>
#import "Command.h"

NS_ASSUME_NONNULL_BEGIN

@interface CommandManager : NSObject

@property (nonatomic, strong, readwrite) NSMutableArray <Command *> *arrayCommands;

/* 單例 **/
+ (instancetype)shareInstance;

/* 執(zhí)行命令 **/
+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion;

/* 取消命令 **/
+ (void)cancleCommand:(Command *)cmd;

@end

NS_ASSUME_NONNULL_END

#import "CommandManager.h"

@implementation CommandManager

/* 單例 **/
+ (instancetype)shareInstance{
    static CommandManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super allocWithZone:NULL]init];
    });
    return instance;
}


+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    return [self shareInstance];
}


- (id)copy{
    return self;
}


/* 執(zhí)行命令 **/
+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion {
    if (cmd) {
        // 如果命令正在執(zhí)行中不做處理,否則添加并執(zhí)行命令
        if (![self isExecutingCommand:cmd]) {
            // 添加到命令容器中
            [[[self shareInstance] arrayCommands] addObject:cmd];
            // 設(shè)置命令執(zhí)行完成的回調(diào)
            cmd.completion = completion;
            // 執(zhí)行命令
            [cmd execute];
        }
    }
}

/* 取消命令 **/
+ (void)cancleCommand:(Command *)cmd {
    if (cmd) {
        // 從命令容器中移除
        [[[self shareInstance] arrayCommands] removeObject:cmd];
        // 取消命令執(zhí)行
        [cmd cancle];
    }
}

/* 此命令是否正在執(zhí)行中 **/
+ (BOOL)isExecutingCommand:(Command *)cmd {
    if (cmd) {
        NSArray *cmds = [[self shareInstance] arrayCommands];
        for (Command *acmd in cmds) {
            if (acmd == cmd) {
                return YES;
            }
        }
    }
    return NO;
}

@end
?著作權(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)容

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