命令模式就是將行為參數(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í)例:

命令基礎(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