命令模式就是将行为参数化,降低代码重合度的
项目使用的场景比如:微博的点赞、评论和转发
1、定义:
(1)将一个请求封装成为一个对象,从而让用户使用不同的请求将客户端参数化
(2)对请求排队或者纪录请求日志,以及支持撤销操作
2、命令模式-应用场景?
当需要将方法调用包装成一个对象,以延时方法调用,或者让其他组件在对其内部实现细节不了解的情况下进行调用的时候可以使用命令模式
场景一:应用程序支持撤销和恢复
场景二:记录请求日志,当系统故障这些命令可以重新被执行
场景三:想用对象参数化一个动作以执行操作,并且用不同命令对象来替换回调函数
3、命令模式-角色划分?——>有很多变种(演示变种)
行为设计模式中一种
角色一:接收者(Receiver作用:负责具体的功能实现->具体实现细节)
角色二:命令接口(协议)(Command:命令抽象)
角色三:具体的命令(ConcreteCmmand:具体的命令,作用:负责调用接收者逻辑方法,行为方法)
角色四:请求者角色(Invoker:调用执行命令)
角色五:客户端
备注:原文的demo与实例的方式不一样
实例:
image.png
命令基础类
#import <Foundation/Foundation.h>
@class Command;
typedef void(^CommandCompletionCallBack)(Command* cmd);
@interface Command : NSObject
@property (nonatomic, copy, readwrite) CommandCompletionCallBack completion;
/**
执行
*/
- (void)execute;
/**
撤销
*/
- (void)cancle;
/**
完成
*/
- (void)done;
@end
#import "Command.h"
#import "CommandManager.h"
@implementation Command
/**
执行
*/
- (void)execute {
// override to subclass
// 在继承的子类中,执行对应的命令业务,最后要调用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;
/* 执行命令 **/
+ (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;
}
/* 执行命令 **/
+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion {
if (cmd) {
// 如果命令正在执行中不做处理,否则添加并执行命令
if (![self isExecutingCommand:cmd]) {
// 添加到命令容器中
[[[self shareInstance] arrayCommands] addObject:cmd];
// 设置命令执行完成的回调
cmd.completion = completion;
// 执行命令
[cmd execute];
}
}
}
/* 取消命令 **/
+ (void)cancleCommand:(Command *)cmd {
if (cmd) {
// 从命令容器中移除
[[[self shareInstance] arrayCommands] removeObject:cmd];
// 取消命令执行
[cmd cancle];
}
}
/* 此命令是否正在执行中 **/
+ (BOOL)isExecutingCommand:(Command *)cmd {
if (cmd) {
NSArray *cmds = [[self shareInstance] arrayCommands];
for (Command *acmd in cmds) {
if (acmd == cmd) {
return YES;
}
}
}
return NO;
}
@end
网友评论