设计模式-命令模式

定义: 把一个请求封装为一个对象,从而让我们可用不同的请求对客户端进行参数化;以及支持可撤销的操作.将发出命令的责任和执行命令的责任分割.

实例:
例如:遥控器是一个调用者,不同的按钮代表不同的命令,而电视是接受者.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 命令
@interface Command : NSObject

@property (nonatomic, assign) SEL sel;
@property (nonatomic, strong) NSObject *target;

- (void)execute;

@end

@implementation Command

- (void)execute
{
[self.target perfromSelector:_sel withObject:nil];
}

@end

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 调用者
@interface Controller : NSObject

// 执行命令
- (void)invokeCommand:(Command *)command;
// 取消命令
- (void)cancelCommand:(Command *)command;

@end

@implementation Controller

- (void)invokeCommand:(Command *)command
{
[command excute];
}

- (void)cancelCommand:(Command *)command
{
}

@end

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 电视机
@interface TV : NSObject

- (void)turnOn;

- (void)turnOff;

@end

@implementation TV

- (void)turnOn
{
NSLog(@"打开电视机");
}

- (void)turnOff
{
NSLog(@"关闭电视机");
}

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TV *tv = [TV new];

Command *one = [Command new];
one.sel = @selector(turnOn):
one.target = tv;

Command *two = [Command new];
two.sel = @selector(turnOn):
two.target = tv;

Controller *controller = [Controller new];

[controller invokCommand:one];
[controller invokCommand:two];

类图:(这里的图和实现有些差别, 实现上通过Target-Action对具体类进行了简化), 完整类图如下:

优点:

  • 降低系统的耦合度。
  • 新的命令可以很容易地加入到系统中。
  • 以比较容易地设计一个命令队列和宏命令(组合命令)。

缺点:

  • 使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

总结:
命令模式的组合使用,可以将复杂的业务进行逐个的拆分