一、命令模式
1、概念
命令对象封装了如何对目标执行指令的信息,因此客户端或调用者不必了解目标的任何细节,却仍可以对他执行任何已有的操作。通过把请求封装成对象,客 户端可以把它参数化并置入队列或日志中,也能够支持可撤销操作。命令对象将一个或多个动作绑定到特定的接收器。命令模式消除了作为对象的动作和执行它的接收器之间的绑定。
2、应用场景
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
3、模式中角色
抽象命令(Command): 定义命令的接口,声明执行的方法。
具体命令(ConcreteCommand): 具体命令,实现要执行的方法,它通常是“虚”的实现;通常会有接收者,并调用接收者的功能来完成命令要执行的操作。
接收者(Receiver): 真正执行命令的对象。任何类都可能成为一个接收者,只要能实现命令要求实现的相应功能。
调用者(Invoker): 要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象,是存储命令对象的容器,以便进行记录和撤销操作。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
客户端(Client): 命令由客户端来创建,并设置命令的接收者。
4、Demo
接收者:
Receiver.h
#import <UIKit/UIKit.h>
@interface Receiver : NSObject {
CGFloat _white; // 白的
CGFloat _alpha; // 透明度
}
// 接收者的view
@property (nonatomic, strong) UIView *receiverView;
// 变暗的接口
- (void)mackeDarker:(CGFloat)pamameter;
// 变亮的接口
- (void)mackeLighter:(CGFloat)pamameter;
@end
Receiver.m
#import "Receiver.h"
@implementation Receiver
- (void)setReceiverView:(UIView *)receiverView {
// 获取数值
_receiverView = receiverView;
UIColor *color = _receiverView.backgroundColor;
[color getWhite:&_white alpha:&_alpha];
}
// 变暗的接口
- (void)mackeDarker:(CGFloat)pamameter {
_white -= pamameter;
// 设置取值范围
_white = MAX(0, _white);
// 设置背景色
_receiverView.backgroundColor = [UIColor colorWithWhite:_white alpha:_alpha];
}
// 变亮的接口
- (void)mackeLighter:(CGFloat)pamameter {
_white += pamameter;
// 设置取值范围
_white = MIN(1, _white);
// 设置背景色
_receiverView.backgroundColor = [UIColor colorWithWhite:_white alpha:_alpha];
}
@end
抽象命令:
CommandProtocol.h
#import <Foundation/Foundation.h>
@protocol CommandProtocol <NSObject>
// 执行命令
- (void)excute;
// 撤销命令
- (void)backExcute;
@end
具体命令:
DarkerCommand.h
#import <Foundation/Foundation.h>
#import "CommandProtocol.h"
#import "Receiver.h"
@interface DarkerCommand : NSObject <CommandProtocol>
// 绑定接收器
- (instancetype)initWithReceiver:(Receiver *)receiver paramter:(CGFloat)paramter;
@end
DarkerCommand.m
#import "DarkerCommand.h"
@interface DarkerCommand ()
@property (nonatomic, strong) Receiver *receiver;
@property (nonatomic, assign) CGFloat paramter;
@end
@implementation DarkerCommand
- (instancetype)initWithReceiver:(Receiver *)receiver paramter:(CGFloat)paramter {
self = [super init];
if (self) {
self.receiver = receiver;
self.paramter = paramter;
}
return self;
}
// 执行命令
- (void)excute {
[self.receiver mackeDarker:self.paramter];
}
// 撤销命令
- (void)backExcute {
[self.receiver mackeLighter:self.paramter];
}
@end
LighterCommand.h
#import <Foundation/Foundation.h>
#import "CommandProtocol.h"
#import "Receiver.h"
@interface LighterCommand : NSObject <CommandProtocol>
// 绑定接收器
- (instancetype)initWithReceiver:(Receiver *)receiver paramter:(CGFloat)paramter;
@end
LighterCommand.m
#import "LighterCommand.h"
@interface LighterCommand ()
@property (nonatomic, strong) Receiver *receiver;
@property (nonatomic, assign) CGFloat paramter;
@end
@implementation LighterCommand
- (instancetype)initWithReceiver:(Receiver *)receiver paramter:(CGFloat)paramter {
self = [super init];
if (self) {
self.receiver = receiver;
self.paramter = paramter;
}
return self;
}
// 执行命令
- (void)excute {
[self.receiver mackeLighter:self.paramter];
}
// 撤销命令
- (void)backExcute {
[self.receiver mackeDarker:self.paramter];
}
@end
命令调用者只能有一个对象,采用单例模式
Invoker.h
#import <Foundation/Foundation.h>
#import "CommandProtocol.h"
@interface Invoker : NSObject
+ (instancetype)sharedInstance;
// 回退指令
- (void)goBack;
// 添加操作指令
- (void)addAndExcute:(id <CommandProtocol>)command;
@end
Invoker.m
#i