iOS设计模式:命令
2017-03-02 本文已影响49人
younger_times

视频教程-极客学院
ps:感觉打的一手好广告啊,因为自己不太爱看视频,但这类又必须看才能明白。粘贴源代码是为了以后查阅方便,也注释了自己的理解。
电视的,遥控器,电视机,接收器。遥控器发送指令,由接收器接收并转化为电视机的信号。接收器和遥控器并不是必须的。
自我理解:命令模式由Command进行了一些约束(约束规定了一些操作),具体的ConcreteCommand进行实际操作,比如发送“提高透明度”,传给了Receiver,Receiver同时对透明度的增加也是在Receiver里面完成的。Invoker则是对执行命令进行存储。Client则只是要改变的视图层给了Receiver,具体操作都在Receiver里。没事就看看,慢慢消化。
Receiver.h(Receiver)
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Receiver : NSObject {
CGFloat _hud;
CGFloat _saturation;
CGFloat _brightness;
CGFloat _alpha;
}
/**
* 被服务对象
*/
@property (nonatomic, weak) UIView *clientView;#比如说,电视。
/**
* 变暗
*
* @param pamameter 操作系数
*/
- (void)makeDarker:(CGFloat)pamameter;
/**
* 变亮
*
* @param pamameter 操作系数
*/
- (void)makeLighter:(CGFloat)pamameter;
@end
#import "Receiver.h"
@implementation Receiver
- (void)setClientView:(UIView *)clientView {
_clientView = clientView;
UIColor *color = _clientView.backgroundColor;
[color getHue:&_hud
saturation:&_saturation
brightness:&_brightness
alpha:&_alpha];
}
- (void)makeDarker:(CGFloat)pamameter {
_brightness -= pamameter;
_brightness = MAX(0, _brightness);
_clientView.backgroundColor = [UIColor colorWithHue:_hud
saturation:_saturation
brightness:_brightness
alpha:_alpha];
}
- (void)makeLighter:(CGFloat)pamameter {
_brightness += pamameter;
_brightness = MIN(1, _brightness);
_clientView.backgroundColor = [UIColor colorWithHue:_hud
saturation:_saturation
brightness:_brightness
alpha:_alpha];
}
CommandProtocol(Command)
制定协议,由UML图看出。
#import <Foundation/Foundation.h>
#import "Receiver.h"
@protocol CommandProtocol <NSObject>
@required
/**
* 命令的执行
*/
- (void)excute;
/**
* 撤销命令
*/
- (void)rollBackExcute;
@end
DarkerCommand(ConcreteCommand)
#import <Foundation/Foundation.h>
#import "CommandProtocol.h"
@interface DarkerCommand : NSObject <CommandProtocol>
/**
* 与接收器绑定并设置参数
*
* @param receiver 接收器
* @param paramter 参数
*/
- (instancetype)initWithReceiver:(Receiver *)receiver paramter:(CGFloat)paramter;
@end
#import "DarkerCommand.h"
@interface DarkerCommand ()
@property (nonatomic, weak) Receiver *receiver;
@property (nonatomic) 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 makeDarker:self.paramter];
}
- (void)rollBackExcute {
[self.receiver makeLighter:self.paramter];
}
LighterCommond(ConcreteCommand)
#import <Foundation/Foundation.h>
#import "CommandProtocol.h"
@interface LighterCommond : NSObject <CommandProtocol>
/**
* 与接收器绑定并设置参数
*
* @param receiver 接收器
* @param paramter 参数
*/
- (instancetype)initWithReceiver:(Receiver *)receiver paramter:(CGFloat)paramter;
@end
#import "LighterCommond.h"
@interface LighterCommond ()
@property (nonatomic, weak) Receiver *receiver;
@property (nonatomic) CGFloat paramter;
@end
@implementation LighterCommond
- (instancetype)initWithReceiver:(Receiver *)receiver paramter:(CGFloat)paramter {
self = [super init];
if (self) {
self.receiver = receiver;
self.paramter = paramter;
}
return self;
}
- (void)excute {
[self.receiver makeLighter:self.paramter];
}
- (void)rollBackExcute {
[self.receiver makeDarker:self.paramter];
}
@end
Invoker(Invoker)
对执行命令的存储
@interface Invoker : NSObject
+ (instancetype)shareInstance;
/**
* 回退操作
*/
- (void)rollBack;
/**
* 添加指令操作
*
* @param command 指令
*/
- (void)addAndExcute:(id <CommandProtocol>)command;
@end
#import "Invoker.h"
@interface Invoker ()
@property (nonatomic, strong) NSMutableArray *queue;
@end
@implementation Invoker
+ (instancetype)shareInstance {
static Invoker *shareInstanceValue = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
shareInstanceValue = [[Invoker alloc] init];
shareInstanceValue.queue = [NSMutableArray array];
});
return shareInstanceValue;
}
- (void)rollBack {
id <CommandProtocol> command = self.queue.lastObject;
[command rollBackExcute];
[self.queue removeLastObject];
}
- (void)addAndExcute:(id <CommandProtocol>)command {
NSParameterAssert(command);
[self.queue addObject:command];
[command excute];
}
@end
使用
#import "ViewController.h"
#import "Receiver.h"
#import "Invoker.h"
#import "DarkerCommand.h"
#import "LighterCommond.h"
typedef enum : NSUInteger {
kAddButtonTag = 10, // 增加按钮枚举值
kDelButtonTag, // 减少按钮枚举值
kRolButtonTag, // 回退按钮枚举值
} ViewControllerEnumValue;
@interface ViewController ()
@property (nonatomic, strong) UIButton *addButton;
@property (nonatomic, strong) UIButton *delButton;
@property (nonatomic, strong) UIButton *rolButton;
@property (nonatomic, strong) Receiver *receiver;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 接收器
self.receiver = [[Receiver alloc] init];
self.receiver.clientView = self.view;
// 初始化按钮
[self initButtons];
}
- (void)buttonsEvent:(UIButton *)button {
if (button.tag == kAddButtonTag) {
//LighterCommond, DarkerCommand我写进了懒加载里面
NSLog(@"增加操作");
LighterCommond *commond = [[LighterCommond alloc] initWithReceiver:self.receiver paramter:0.1];
[[Invoker shareInstance] addAndExcute:commond];
//Invoker 对操作进行了存储,也可以不存储,因为LighterCommond 遵守了协议。有excute方法,调用receiver执行操作。虽然我不知道这么做,是否违背命令模式。如果违背了麻烦告诉我一声。
} else if (button.tag == kDelButtonTag) {
NSLog(@"减少操作");
DarkerCommand *commond = [[DarkerCommand alloc] initWithReceiver:self.receiver paramter:0.1];
[[Invoker shareInstance] addAndExcute:commond];
} else if (button.tag == kRolButtonTag) {
NSLog(@"回退操作");
[[Invoker shareInstance] rollBack];
}
}
#pragma mark - 无关初始化
- (void)initButtons {
// delButton
self.delButton = [[UIButton alloc] initWithFrame:CGRectMake(10, 25, 30, 30)];
self.delButton.tag = kDelButtonTag;
self.delButton.layer.borderWidth = 1.f;
[self.delButton setTitle:@"-"
forState:UIControlStateNormal];
[self.delButton setTitleColor:[UIColor redColor]
forState:UIControlStateNormal];
[self.delButton addTarget:self
action:@selector(buttonsEvent:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.delButton];
// addButton
self.addButton = [[UIButton alloc] initWithFrame:CGRectMake(10 + 40, 25, 30, 30)];
self.addButton.tag = kAddButtonTag;
self.addButton.layer.borderWidth = 1.f;
[self.addButton setTitle:@"+"
forState:UIControlStateNormal];
[self.addButton setTitleColor:[UIColor redColor]
forState:UIControlStateNormal];
[self.addButton addTarget:self
action:@selector(buttonsEvent:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.addButton];
// rolButton
self.rolButton = [[UIButton alloc] initWithFrame:CGRectMake(10 + 80, 25, 90, 30)];
self.rolButton.tag = kRolButtonTag;
self.rolButton.layer.borderWidth = 1.f;
[self.rolButton setTitle:@"rollBack"
forState:UIControlStateNormal];
[self.rolButton setTitleColor:[UIColor redColor]
forState:UIControlStateNormal];
[self.rolButton addTarget:self
action:@selector(buttonsEvent:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.rolButton];
}
@end