Oh!Coder

Coding Life

Objective C--职责链模式

| Comments

今天想和大家分享的是职责链模式。闲话先不多说,先给出一个简单的定义。

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

职责链模式的一个很重要的特点是,当客户发出请求之后,客户端并不知道哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态地重新组织和分配责任。

下面给出类结构图。

pic

从上图可以看出,当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。这样做的好处是请求者不用管哪个对象来处理,反正最终是要被某一个对象处理就是了。也就是说接收者和发送者都没有对方的明确信息,且链中的对象自己也不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。

这些特点的好处是我们可以随时增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。但是,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,所以这更需要我们事先考虑全面。

好的,说了这么多,还是老样子,给大家展示一下简单的示意代码。

注意:本文所有代码均在ARC环境下编译通过。

  • Handlers类接口
1
2
3
4
5
6
7
8
#import <Foundation/Foundation.h>

@interface Handlers :NSObject{
    Handlers *mySuccessor;
}
-(void)SetSuccessor:(Handlers*)successor;
-(void)HandleRequest:(int)request;
@end
  • Handlers类实现
1
2
3
4
5
6
7
8
9
10
#import "Handlers.h"

@implementation Handlers
-(void)SetSuccessor:(Handlers *)successor{
    mySuccessor = successor;
}
-(void)HandleRequest:(int)request{
    return;
}
@end
  • ConcreteHandler1类接口
1
2
3
4
5
#import "Handlers.h"

@interface ConcreteHandler1:Handlers
-(void)HandleRequest:(int)request;
@end
  • ConcreteHandler1类实现
1
2
3
4
5
6
7
8
9
10
11
12
#import "ConcreteHandler1.h"

@implementation ConcreteHandler1
-(void)HandleRequest:(int)request{
    if (request >=0 && request <10) {
        NSLog(@"ConcreteHandler1处理%d", request);
    }
    else if (mySuccessor !=nil) {
            [mySuccessor HandleRequest:request];
    }
}
@end
  • ConcreteHandler2类接口
1
2
3
4
#import "Handlers.h"

@interface ConcreteHandler2 :Handlers
@end
  • ConcreteHandler2类实现
1
2
3
4
5
6
7
8
9
10
11
12
#import "ConcreteHandler2.h"

@implementation ConcreteHandler2
-(void)HandleRequest:(int)request{
    if (request >=10 && request <20) {
        NSLog(@"ConcreteHandler2处理%d", request);
    }
    else if(mySuccessor !=nil) {
        [mySuccessor HandleRequest:request];
    }
}
@end
  • ConcreteHandler3类接口
1
2
3
4
#import "Handlers.h"

@interface ConcreteHandler3 :Handlers
@end
  • ConcreteHandler3类实现
1
2
3
4
5
6
7
8
9
10
11
12
#import "ConcreteHandler3.h"

@implementation ConcreteHandler3
-(void)HandleRequest:(int)request{
    if (request >=20 && request <30) {
        NSLog(@"ConcreteHandler3处理%d", request);
    }
    else if (mySuccessor !=nil) {
        [mySuccessor HandleRequest:request];
    }
}
@end
  • Main方法调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#import <Foundation/Foundation.h>

int main(int argc,const char * argv[])
{
    @autoreleasepool{
        Handlers *h1 = [[ConcreteHandler1 alloc]init];
        Handlers *h2 = [[ConcreteHandler2 alloc]init];
        Handlers *h3 = [[ConcreteHandler3 alloc]init];
        [h1 SetSuccessor:h2];
        [h2 SetSuccessor:h3];
        int requests[] = {2,5,14,22,18,3,27,20};
        for (int i =0; i <8; i++) {
            [h1 HandleRequest:requests[i]];
        }
    }
    return 0;
}

好啦,代码展示完毕!收工!

Comments