Cowboy Tech

iOS设计模式-责任链

快递分拣中心

  1. 传送带 —> 线性表
  2. 包裹 —> 符合某种规范的物品
  3. 货物种类 —> 特定种类的货物

特点:提升效率

责任链模式

定义:责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

步骤:

  1. 将责任抽象成对象
  2. 将责任对象链接起来
  3. 处理输入的事件

ChainProtocol

protocol ChainProtocol <NSObject>

//设置继任者
- (void)setSuccessor:(id <ChainProtocol>)successor;

//获取继任者
- (id <ChainProtocol>)successor;

//处理请求
- (void)handleRequest:(id)request;

@end

对输入文本进行类别检测

  1. 职能分解,有电话号码检测,邮箱检测,用户名检测。类似不同种类的包裹
  2. 设定共有的接口。比如不同种类的产品都能装入一个纸箱
  3. 严格说来还要设定一个尾节点,处理什么都不是的情况
  4. 如果用if else的话,就不能进行拆解

ChainProtocol

@protocol ChainProtocol <NSObject>
- (void)setSuccessor:(id <ChainProtocol>)successor;
- (id <ChainProtocol>)successor;
- (void)handleRequest:(id)request;
@end

EmailChain

@interface EmailChain : NSObject <ChainProtocol>

@end

@interface EmailChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation EmailChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

NSString *string = request;

BOOL isMatch = [string isMatch:RX(@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")];
if (isMatch == NO) {

    [self.nextSuccessor handleRequest:string];

} else {

    NSLog(@"%@ 是邮箱", string);
}
}

@end

PhoneNumChain

@interface PhoneNumChain : NSObject <ChainProtocol>

@end

@interface PhoneNumChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation PhoneNumChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

NSString *string = request;

BOOL isMatch = [string isMatch:RX(@"^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$")];
if (isMatch == NO) {

    [self.nextSuccessor handleRequest:string];

} else {

    NSLog(@"%@ 是电话号码", string);
}
}

@end

UserNameChain

@interface UserNameChain : NSObject <ChainProtocol>

@end

@interface UserNameChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation UserNameChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

NSString *string = request;

BOOL isMatch = [string isMatch:RX(@"^[A-Za-z0-9]{6,20}+$")];
if (isMatch == NO) {

    [self.nextSuccessor handleRequest:string];

} else {

    NSLog(@"%@ 是用户名", string);
}
}

@end

HeadChain

@interface HeadChain : NSObject <ChainProtocol>

@end

@interface HeadChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation HeadChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

    self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

    return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

    [self.nextSuccessor handleRequest:request];
}


@end

ViewController

@interface ViewController ()
@property (nonatomic, strong) HeadChain      *head;
@property (nonatomic, strong) PhoneNumChain  *phoneNum;
@property (nonatomic, strong) EmailChain     *email;
@property (nonatomic, strong) UserNameChain  *userName;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 创建责任对象
    self.head     = [HeadChain new];
    self.phoneNum = [PhoneNumChain new];
    self.email    = [EmailChain new];
    self.userName = [UserNameChain new];

    // 链接责任链对象
    self.head.successor     = self.phoneNum;
    self.phoneNum.successor = self.email;
    self.email.successor    = self.userName;

    // 处理请求
    [self.head handleRequest:@"349323YX"];
}
@end

对输入文本进行”全类别”检测

ChainProtocol

@protocol ChainProtocol <NSObject>
- (void)setSuccessor:(id <ChainProtocol>)successor;
- (id <ChainProtocol>)successor;
- (void)handleRequest:(id)request;

@end

HeadChain

@interface HeadChain : NSObject <ChainProtocol>

@end

@interface HeadChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation HeadChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

[self.nextSuccessor handleRequest:request];
}
@end

RequestEvent

@interface RequestEvent : NSObject

@property (nonatomic, strong) NSString            *string;
@property (nonatomic, strong) NSMutableDictionary *infomation;

@end

@implementation RequestEvent

- (instancetype)init {

    self = [super init];

    if (self) {

        self.infomation = [NSMutableDictionary dictionary];
    }

    return self;
}

@end

EmailChain

@interface EmailChain : NSObject <ChainProtocol>

@end

@interface EmailChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation EmailChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

RequestEvent *event = request;

BOOL isMatch = [event.string isMatch:RX(@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")];
if (isMatch == NO) {

    event.infomation[@"Email"] = @(NO);

} else {

    event.infomation[@"Email"] = @(YES);
}

[self.nextSuccessor handleRequest:request];
}

@end

PhoneNumChain

@interface PhoneNumChain : NSObject <ChainProtocol>

@end

@interface PhoneNumChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation PhoneNumChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

RequestEvent *event = request;

BOOL isMatch = [event.string isMatch:RX(@"^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$")];
if (isMatch == NO) {

    event.infomation[@"PhoneNumber"] = @(NO);

} else {

    event.infomation[@"PhoneNumber"] = @(YES);
}

[self.nextSuccessor handleRequest:request];
}

@end

UserNameChain

@interface UserNameChain : NSObject <ChainProtocol>

@end

@interface UserNameChain ()

@property (nonatomic, strong) id <ChainProtocol> nextSuccessor;

@end

@implementation UserNameChain

- (void)setSuccessor:(id <ChainProtocol>)successor {

self.nextSuccessor = successor;
}

- (id <ChainProtocol>)successor {

return self.nextSuccessor;
}

- (void)handleRequest:(id)request {

RequestEvent *event = request;

BOOL isMatch = [event.string isMatch:RX(@"^[A-Za-z0-9]{6,20}+$")];
if (isMatch == NO) {

    event.infomation[@"UserName"] = @(NO);

} else {

    event.infomation[@"UserName"] = @(YES);
}

[self.nextSuccessor handleRequest:request];
}

@end

ViewController

@interface ViewController ()
@property (nonatomic, strong) HeadChain      *head;
@property (nonatomic, strong) PhoneNumChain  *phoneNum;
@property (nonatomic, strong) EmailChain     *email;
@property (nonatomic, strong) UserNameChain  *userName;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// 创建责任对象
self.head     = [HeadChain new];
self.phoneNum = [PhoneNumChain new];
self.email    = [EmailChain new];
self.userName = [UserNameChain new];

// 链接责任链对象
self.head.successor     = self.phoneNum;
self.phoneNum.successor = self.email;
self.email.successor    = self.userName;

RequestEvent *event = [RequestEvent new];
event.string        = @"349323YX@qq.com";

// 处理请求
[self.head handleRequest:event];

NSLog(@"%@", event.infomation);

}
@end