简单的举个例子就比如说电灯,开关和风扇,我们可以通过开关去控制风扇和电灯的开和关。其中开关是发送者,电线是命令对象,而风扇和电灯就是接受者。电线是可以换的,所以就是说开关可以做两个不同的操作
命令模式:其实就是把请求封装成一个对象,从而可以使用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作
这样的好处就在于我们在给接受者去发送请求的时候,然后让接受者去执行,可能发送请求的对象都不知道接受请求的对象是谁,以及执行了什么操作,可以将调用请求的和接受请求的进行一个解耦
下面简单的举一个电脑开关机的例子,首先我们先定义命令接口
@protocol ComputerCommandProtocol<NSObject>
//操作->具体实现方法
-(void)execute;
@end
然后去定义具体的命令对象遵循命令接口,类定义如下所示
//命令角色特点:持有接收者引用
@interface MacStartupCommand : NSObject<ComputerCommandProtocol>
- (instancetype)init:(MacComputer*)computer;
@end
具体的命令对象的实现如下所示
#import "MacStartupCommand.h"
@interface MacStartupCommand()
//引用接收者对象
@property(nonatomic, strong) MacComputer* computer;
@end
@implementation MacStartupCommand
- (instancetype)init:(MacComputer*)computer{
self = [super init];
if (self) {
self.computer = computer;
}
return self;
}
-(void)execute{
//具体实现->调用具体逻辑
[self.computer startup];
}
@end
然后我们去看接收者对象的类定义
//接收者
@interface MacComputer : NSObject
//开机
-(void)startup;
再去看接收者对象的具体实现
#import "MacComputer.h"
//具体实现
@implementation MacComputer
//开机
-(void)startup{
//具体实现
NSLog(@"开机...");
}
@end
再然后我们再去看看调用者对象的类定义
#import <Foundation/Foundation.h>
#import "MacStartupCommand.h"
//请求者
@interface MacInvoker : NSObject
- (instancetype)init:(MacStartupCommand*)startup shutdown:(MacShutdownCommand*)shutdown;
-(void)start;
@end
再去看看其的具体实现
#import "MacInvoker.h"
@interface MacInvoker()
@property(nonatomic, strong) id<ComputerCommandProtocol> startupCommand;
@end
@implementation MacInvoker
- (instancetype)init:(MacStartupCommand*)startup shutdown:(MacShutdownCommand*)shutdown{
self = [super init];
if (self) {
self.startupCommand = startup;
}
return self;
}
-(void)start{
//调用命令
[self.startupCommand execute];
}
@end
接下来看下他们的结构,应该就会有一个基本的概念了
一般命令模式当中有四个对象
调用者Invoker:就是调用者
接受者Receiver:就是接收调用者请求执行操作的目标的对象
抽象命令Command:定义命令的接口,声明执行的方法
具体命令ConcreteCommand:会去创建一个具体命令对象并设定它的接收者。一般来说会去引用接收者,并且调用接收者的功能来完成命令要执行的操作
命令模式的用途:可以用做画图,自定义相机,滤镜效果等等。如果我们想要撤销回退某些操作就可以用命令模式。命令模式的典型应用其实就是支持应用程序的撤销和恢复操作