美文网首页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