
//Handler
@interface Rescuer : NSObject
@property (nonatomic, strong) Rescuer *next;
@property (nonatomic) NSInteger code;
//HandleRequest()
- (void)help:(NSInteger)code;
- (void)toHelp;
@end
@implementation Rescuer
- (instancetype)init {
self = [super init];
if (self) {
_code = -1;
}
return self;
}
- (void)help:(NSInteger)code {
if (self.code == code) {
[self toHelp];
} else if (self.next != nil) {
[self.next help:code];
}
}
- (void)toHelp {
}
@end
//ConcreteHandler
@interface Firefighter : Rescuer
- (instancetype)initWithNext:(Rescuer *)next;
@end
@implementation Firefighter
- (instancetype)initWithNext:(Rescuer *)next {
self = [super init];
if (self) {
self.next = next;
self.code = 1;
}
return self;
}
- (void)toHelp {
NSLog(@"call firefighters");
}
@end
//ConcreteHandler
@interface Police : Rescuer
- (instancetype)initWithNext:(Rescuer *)next;
@end
@implementation Police
- (instancetype)initWithNext:(Rescuer *)next {
self = [super init];
if (self) {
self.next = next;
self.code = 2;
}
return self;
}
- (void)toHelp {
NSLog(@"call the police");
}
@end
//ConcreteHandler
@interface Ambulance : Rescuer
- (instancetype)initWithNext:(Rescuer *)next;
@end
@implementation Ambulance
- (instancetype)initWithNext:(Rescuer *)next {
self = [super init];
if (self) {
self.next = next;
self.code = 3;
}
return self;
}
- (void)toHelp {
NSLog(@"call an ambulance");
}
@end
//Client
Ambulance *ambulance = [[Ambulance alloc] initWithNext:nil];
Police *police = [[Police alloc] initWithNext:ambulance];
Firefighter *firefighter = [[Firefighter alloc] initWithNext:police];
[firefighter help:1];
//printed: call firefighters
[firefighter help:2];
//printed: call the police
[firefighter help:3];
//printed: call an ambulance
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.Read moreThe problem. A support service receives requests of different sizes. A small one goes to an assistant, a larger one to a manager, a very large one to a director. If the code that sends a request had to choose the receiver itself, it would have to know every receiver and every rule. Each new receiver would mean a change in the sender. The idea. The receivers, called handlers, are placed in a fixed order: the chain. The sender gives a request only to the first handler. Each handler checks whether the request is its own. If it is, the handler does the work, and the request goes no further. If it is not, the handler passes the request to the next one. The sender does not know which handler will answer, or whether any will. How to read the example. Several handlers are joined into a chain. Each one decides by its own rule whether a request is its own. The client code sends several requests, always to the start of the chain. Each request moves along the chain until a handler accepts it. In most languages each handler keeps a link to the next one; in some, the chain is a simple list checked in order. Some examples also send a request that no handler accepts, and the output reports it. When to use it. Use a chain when several objects may handle a request, and their set or their order may change. Do not use it when the receiver is always the same: a direct call is simpler and easier to follow. A common mistake. Forgetting the end of the chain. A request that no handler accepts is then lost without any message. Decide what happens at the end: an error, a default handler or a clear report. |