好久没写博了,突然觉得自己该慢慢的培养写文章的好习惯,所以就拿设计模式开刀记录自己学习的点滴。好了不说了直接上干货。
责任链模式的定义:
它包含了一些命令对象和一些处理对象,每个处理对象决定它能处理那些命令对象,它也知道应该把自己不能处理的命令对象交下一个处理对象,该模式还描述了往该链添加新的处理对象的方法。
这里我们以公司为例,公司总有不同的角色如:总裁(CEO)、副总裁(Vice President)、总监(Direct)、主管(Charge)、小组组长(Group Leader),他们每个角色都拥有批准员工请假的权利,但是每个人批准请他的天数不一样。我们假如小组组长只能批小于10天的假期,主管小于20天,总监小于30天,副总裁小于40天,总裁小于50天,超过50天的总裁一口回绝。这个层次关系是一层一层的传递的,小组组长不能批的就上报给主管批,主管不能批的就上报给总监批,以此类推。比如说某个员工想请28天的假期,那么0<28<30请教申请交给小组组长后最后会由总监批准。由于从以前的JAVAEE开发转为了iOS开发,所以以后的代码基本上是以Objective-C为主了。先看一看项目结构:
项目结构如上图,下面直接上代码:
ChainHandler.h(责任链类声明文件)
#import <Foundation/Foundation.h>
@protocol ChainOfResponsibility <NSObject>
@required
- (void)askForLeaveWithDays:(NSInteger)days;
@end
@interface ChainHandler : NSObject<ChainOfResponsibility>
@property (nonatomic, strong)ChainHandler *successor;
@end
此类中声明了一个ChainOfResponsibility协议,类似Java中的接口,协议中声明了
- (void)askForLeaveWithDays:(NSInteger)days;
方法来表示员工将要请假的天数,并拥有一个自己的实例successor来表示自己的后继,类似于链表(责任链嘛),下面是其实现文件:
ChainHandler.m(责任链类实现文件)
#import "ChainHandler.h"
@implementation ChainHandler
-(void)askForLeaveWithDays:(NSInteger)days
{
NSLog(@"我是最顶层的 我不实现接口");
}
@end
由于他是个抽象接口所以不需要在其中实现什么有意义的代码。
下面是CEO类:
#import "ChainHandler.h"
//CEO
@interface CEO : ChainHandler<ChainOfResponsibility>
@end
#import "CEO.h"
@implementation CEO
-(void)askForLeaveWithDays:(NSInteger)days
{
days < 50 ? NSLog(@"%@批准过请%ld天假",[self class], days) : NSLog(@"不准伱的假");
}
@end
后面所有的类都是
ChainHandler(责任链类)的子类,并实现了其askForLeaveWithDays方法,如父总裁类:
#import "ChainHandler.h"
//副总
@interface VicePresident : ChainHandler<ChainOfResponsibility>
@end
#import "VicePresident.h"
@implementation VicePresident
-(void)askForLeaveWithDays:(NSInteger)days
{
days < 40 ? NSLog(@"%@批准过请%ld天假",[self class], days) : [self.successor askForLeaveWithDays:days];
}
@end
后面的总监、主管、小组组长都与副总裁类99%类似 只是把40改成了30、20、10。
下面是一个静态工程返回的已经成链的Handler对象
#import "ChainHandler.h"
#import "CEO.h"
#import "VicePresident.h"
#import "Director.h"
#import "Charge.h"
#import "GroupLeader.h"
#import <Foundation/Foundation.h>
@interface LeaderFactory : NSObject
+ (ChainHandler *)chainHandler;
@end
#import "LeaderFactory.h"
@implementation LeaderFactory
+(ChainHandler *)chainHandler
{
ChainHandler *ceo = [[CEO alloc]init];
VicePresident *vicePresident = [[VicePresident alloc]init];
vicePresident.successor = ceo;
Director *director = [[Director alloc]init];
director.successor = vicePresident;
Charge *charge = [[Charge alloc]init];
charge.successor = director;
ChainHandler *groupLeader = [[GroupLeader alloc]init];
groupLeader.successor = charge;
return groupLeader;
}
@end
可以看出,把主管设为小组组长的后继,总监为主管的后继、副总为总监的后继、总裁为副总的后继,并返回小组组长作为链的开端。下面是main函数
#import "ChainHandler.h"
#import "LeaderFactory.h"
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
ChainHandler *handler = [LeaderFactory chainHandler];
for (int i=0; i<50; i++) {
NSInteger days = arc4random() % 50;
[handler askForLeaveWithDays:days];
}
}
return 0;
}
我们随机生成50个1~50之间的数来表示员工请假的天数。下面是运行结果。
f