APP & program

iOS 设计模式的应用 ⑮ 责任链

2022-05-18  本文已影响0人  _涼城

前言

    如果将很多人的智慧连接成一个链条,每个人都有自己的专长,联合起来就能形成强大的实体,这很像团队成员之间的合作。智慧链条中的每个单元都可以为问题的解决作出贡献。如果一个人不知道如何解决问题,他就会把问题沿着链条向下传,有的时候,即使有人知道如何解决,依旧会把问题传递下去,这样就能完成解决问题的特定过程。

    这种概念对于面向对象的软件设计同样适用,称为责任链模式。比如,让一组对象处理特定的请求,而对这个组添加或删除处理程序都不应影响组的完成性。

什么是责任链模式

   顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链,其避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

责任链模式的类图.png

    Handler 是上传抽象类,定义了一个方法 handlerRequest,处理它知道如何处理的请求对象。ConcreteHandler1ConcreteHandler2 实现了 handlerRequest 来处理它们认识的请求对象。 Handler 也有一个指向另一个同类实例 successor 的引用。当调用 Handler 实例的 handlerRequest 消息不知道如何处理请求时,会用同样的消息发送给 successor

什么时候使用责任链模式

责任链模式的优缺点

责任链模式的优点

  1. 降低耦合度。它将请求的发送者和接收者解耦。
  2. 简化了对象。使得对象不需要知道链的结构。
  3. 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
  4. 增加新的请求处理类很方便。

责任链模式的缺点

  1. 不能保证请求一定被接收。
  2. 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
  3. 可能不容易观察运行时的特征,有碍于除错。

责任链模式的实现

创建抽象类 AbstractLogger,带有详细的日志记录级别。

typedef enum : NSUInteger {
    Info,
    Debug,
    Error,
} LogLevel;

@interface AbstractLogger : NSObject

- (instancetype)initWithLevel:(LogLevel)level;

@property (nonatomic, assign) LogLevel level;

@property (nonatomic, strong) AbstractLogger *nextLogger;

- (void)logMessage:(NSString *)message Level:(LogLevel)level;


- (void)write:(NSString *)message;

@end
@implementation AbstractLogger

- (instancetype)initWithLevel:(LogLevel)level{
    self = [super init];
    if (self) {
        self.level = level;
    }
    return self;
}

- (void)logMessage:(NSString *)message Level:(LogLevel)level{
    if (level == self.level) {
        [self write:message];
    }
    if (self.nextLogger) {
        [self.nextLogger logMessage:message Level:level];
    }
}


- (void)write:(NSString *)message{
    
}

@end

然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。

@interface ConsoleLogger : AbstractLogger

@end
@implementation ConsoleLogger
  
- (void)write:(NSString *)message{
    NSLog(@"Console Logger %@",message);
}

@end
@interface FileLogger : AbstractLogger

@end
@implementation FileLogger

- (void)write:(NSString *)message{
    NSLog(@"File Logger %@",message);
}

@end
@interface ErrorLogger : AbstractLogger

@end
@implementation ErrorLogger
- (void)write:(NSString *)message{
    NSLog(@"Error Logger %@",message);
}

@end

向响应链发送请求

- (void)logMessage{
    AbstractLogger *loggerChain = [self getChainOfLoggers];
    
    [loggerChain logMessage:@"information" Level:Info];
    
    [loggerChain logMessage:@"debug" Level:Debug];

    [loggerChain logMessage:@"error" Level:Error];
}

- (AbstractLogger *)getChainOfLoggers{
    ErrorLogger *errorLogger = [[ErrorLogger alloc] initWithLevel:Error];
    FileLogger *fileLogger = [[FileLogger alloc] initWithLevel:Debug];
    ConsoleLogger *consoleLogger = [[ConsoleLogger alloc] initWithLevel:Info];
    
    [errorLogger setNextLogger:fileLogger];
    [fileLogger setNextLogger:consoleLogger];
    return  errorLogger;
}

Cocoa 中的责任链模式

    应用程序框架包括一个称为响应者链的架构。该链由一系列响应者对象(继承自UIResponder) 事件(例如,鼠标单击)或操作消息被传递并(通常)最终被处理。如果给定的响应者对象不处理特定消息,它会将消息传递给链中的下一个响应者。响应者对象在链中的顺序通常由视图层次结构决定,在层次结构中从较低级别到较高级别的响应者,如果视图由UIViewController对象管理,则视图控制器将成为链中的下一个响应者(事件或操作消息从那里传递到视图的父视图)。响应者链上的事件和动作消息的路径是不同的。

总结

 责任链模式其主要思想是对象引用了同一类型的另一个对象,形成一条链。链中的每个对象实现了同样的方法,处理对链中第一个对象发起的同一个请求。如果一个对象不知道如何处理,就把请求传给下一个响应器。

上一篇 下一篇

猜你喜欢

热点阅读