美文网首页APP & program
iOS 设计模式的应用 ⑮ 责任链

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

作者: _涼城 | 来源:发表于2022-05-18 07:20 被阅读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对象管理,则视图控制器将成为链中的下一个响应者(事件或操作消息从那里传递到视图的父视图)。响应者链上的事件和动作消息的路径是不同的。

总结

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

相关文章

网友评论

    本文标题:iOS 设计模式的应用 ⑮ 责任链

    本文链接:https://www.haomeiwen.com/subject/rxiourtx.html