iOS設(shè)計(jì)模式-組合
原理圖
Command.png
說明
在軟件系統(tǒng)中, "行為請求者"與"行為實(shí)現(xiàn)者"通常呈現(xiàn)一種"緊耦合". 但在某些場合, 不如要對(duì)行為進(jìn)行"記錄, 撤銷\重做\事務(wù)"等處理, 這種無法抵御變化的緊耦合是不合適的. 在這種情況下, 如何將"行為請求者"與"行為實(shí)現(xiàn)者"解耦, 將一組行為抽象為對(duì)象, 實(shí)現(xiàn)二者之間的松耦合, 這就是命令模式.
模式結(jié)構(gòu)
-
Command
定義命令的接口, 聲明執(zhí)行的方法.
-
ConcreteCommand
命令接口實(shí)現(xiàn)對(duì)象, 是"虛"的實(shí)現(xiàn); 通常會(huì)持有接收者, 并調(diào)用接收者的功能來完成命令要執(zhí)行的操作.
-
Invoker
要求命令對(duì)象執(zhí)行請求, 通常會(huì)持有命令對(duì)象, 可以持有很多的命令對(duì)象. 這個(gè)是客戶端真正觸發(fā)命令并要求命令執(zhí)行相應(yīng)操作的地方, 也就是說相當(dāng)于使用命令對(duì)象的入口.
-
Client
創(chuàng)建具體的命令對(duì)象, 并且設(shè)置命令對(duì)象的接收者. 注意這個(gè)不是我們常規(guī)意義上的客戶端, 而是在組裝命令對(duì)象和接收者, 把這個(gè)Client稱為裝配者會(huì)更好理解, 因?yàn)檎嬲褂妹畹目蛻舳耸菑腎nvoker來觸發(fā)執(zhí)行.
模式分析
- 命令模式的本質(zhì)是對(duì)命令進(jìn)行封裝, 將發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分隔開.
- 每一個(gè)命令都是一個(gè)操作: 請求的一方發(fā)出請求, 要求執(zhí)行一個(gè)操作; 接收的一方收到請求, 并執(zhí)行操作.
- 命令模式允許請求的一方和接收的一方獨(dú)立開來, 使得請求的一方不必知道接收的一方的接口, 更不必知道請求是怎樣被接收, 以及操作是否被執(zhí)行, 何時(shí)被執(zhí)行, 以及是怎么執(zhí)行.
- 命令模式使請求本身成為一個(gè)對(duì)象, 這個(gè)對(duì)象和其他對(duì)象一樣可以被存儲(chǔ)和傳遞.
- 命令模式的關(guān)鍵在于引入抽象命令接口, 且發(fā)送者針對(duì)抽象命令接口編程, 只有實(shí)現(xiàn)了抽象命令接口的具體命令才能與接收者相關(guān)聯(lián).
代碼實(shí)現(xiàn)
Client
//
// ViewController.m
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import "ViewController.h"
#import "Light.h"
#import "SwitchOnCommand.h"
#import "SwitchOffCommand.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// client
// receiver
Light *light = [[Light alloc] init];
// concreteCommand
SwitchOnCommand *turnOn = [[SwitchOnCommand alloc] initWithLight:light];
SwitchOffCommand *turnOff = [[SwitchOffCommand alloc] initWithLight:light];
// Invoker command
[turnOn execute];
[turnOff execute];
}
@end
CommandProtocol
//
// CommandProtocol.h
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol CommandProtocol <NSObject>
- (void)execute;
@end
NS_ASSUME_NONNULL_END
ConcreteCommand
//
// SwitchOnCommand.h
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Light.h"
#import "CommandProtocol.h"
NS_ASSUME_NONNULL_BEGIN
@interface SwitchOnCommand : NSObject <CommandProtocol>
- (instancetype)initWithLight:(Light *)light;
@end
NS_ASSUME_NONNULL_END
//
// SwitchOnCommand.m
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import "SwitchOnCommand.h"
@interface SwitchOnCommand()
{
Light *light_;
}
@end
@implementation SwitchOnCommand
- (instancetype)initWithLight:(Light *)light {
self = [super init];
if (self) {
light_ = light;
}
return self;
}
#pragma mark CommandProtocol method
- (void)execute {
[light_ turnOff];
}
@end
//
// SwitchOffCommand.h
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "Light.h"
#import "CommandProtocol.h"
NS_ASSUME_NONNULL_BEGIN
@interface SwitchOffCommand : NSObject <CommandProtocol>
- (instancetype)initWithLight:(Light *)light;
@end
NS_ASSUME_NONNULL_END
//
// SwitchOffCommand.m
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import "SwitchOffCommand.h"
@interface SwitchOffCommand()
{
Light *light_;
}
@end
@implementation SwitchOffCommand
- (instancetype)initWithLight:(Light *)light {
self = [super init];
if (self) {
light_ = light;
}
return self;
}
#pragma mark CommandProtocol method
- (void)execute {
[light_ turnOn];
}
@end
receiver
//
// Light.h
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Light : NSObject
/**
開燈
*/
- (void)turnOn;
/**
關(guān)燈
*/
- (void)turnOff;
@end
NS_ASSUME_NONNULL_END
//
// Light.m
// Command
//
// Created by mye on 2019/3/29.
// Copyright ? 2019 mye. All rights reserved.
//
#import "Light.h"
@implementation Light
- (void)turnOff {
NSLog(@"關(guān)燈");
}
- (void)turnOn {
NSLog(@"開燈");
}
@end