iOS应用设计模式开发中职责链(责任链)模式的实现解析

定义
为了避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,职责链模式又称为责任链模式,它是一种对象行为型模式。(如果你接触过异常处理,那么套用异常处理机制可以更好地理解)。
职责链可以是一条直线,也可以是一个环,还可以是一个树形结构,不过最常见的职责链是直线型,即沿着一条单向的链来传递请求。链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处理,而客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,通过这种方法将请求的发送者和请求的处理者解耦,消除两个角色间的依赖关系,可以自由地组合。

原理结构

上图阐释的是职责连模式的实现原理,主要角色包括:
Handler:抽象处理者。定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。
ConcreteHandler: 具体处理者。具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
Client:客户端
handleRequest:抽象处理者的公用接口,要求每个链式节点都实现这个接口,能够处理客户端发过来的请求数据。
对于每个链式节点,需要满足一下两个条件:
实现抽象处理者(Handler)所定义的抽象接口,能够识别接收的请求;
有一个successor,用于把当前不能处理的请求转发传递到下一个节点,如此才能形成一个链。(successor是指下一个ConcreteHandler的引用,相当于链表里面的next指针)
由于通过上述的编程设计,使得请求和处理该请求的对象完全没有依赖关系,因为客户端甚至不知道是谁处理了这个请求,这样的话,使得整个链式结构很灵活,可以随时添加新的的节点,当然也支持随意调节节点顺序、删除不必要的节点等等操作。

iOS实现
职责链模式的一个很重要的特点是,当客户发出请求之后,客户端并不知道哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态地重新组织和分配责任。

下面给出类结构图。

从上图可以看出,当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。这样做的好处是请求者不用管哪个对象来处理,反正最终是要被某一个对象处理就是了。也就是说接收者和发送者都没有对方的明确信息,且链中的对象自己也不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。

这些特点的好处是我们可以随时增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。但是,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,所以这更需要我们事先考虑全面。

好的,说了这么多,还是老样子,给大家展示一下简单的示意代码。

注意:本文所有代码均在ARC环境下编译通过。

Handlers类接口

代码如下:

#import <Foundation/Foundation.h>

@interface Handlers :NSObject{
    Handlers *mySuccessor;
}
-(void)SetSuccessor:(Handlers*)successor;
-(void)HandleRequest:(int)request;
@end

Handlers类实现

代码如下:

#import "Handlers.h"

@implementation Handlers
-(void)SetSuccessor:(Handlers *)successor{
    mySuccessor = successor;
}
-(void)HandleRequest:(int)request{
    return;
}
@end

ConcreteHandler1类接口

代码如下:

#import "Handlers.h"

@interface ConcreteHandler1:Handlers
-(void)HandleRequest:(int)request;
@end
ConcreteHandler1类实现

#import "ConcreteHandler1.h"

@implementation ConcreteHandler1
-(void)HandleRequest:(int)request{
    if (request >=0 && request <10) {
        NSLog(@"ConcreteHandler1处理%d", request);
    }
    else if (mySuccessor !=nil) {
            [mySuccessor HandleRequest:request];
    }
}
@end

ConcreteHandler2类接口

代码如下:

#import "Handlers.h"

@interface ConcreteHandler2 :Handlers
@end

ConcreteHandler2类实现

代码如下:

#import "ConcreteHandler2.h"

@implementation ConcreteHandler2
-(void)HandleRequest:(int)request{
    if (request >=10 && request <20) {
        NSLog(@"ConcreteHandler2处理%d", request);
    }
    else if(mySuccessor !=nil) {
        [mySuccessor HandleRequest:request];
    }
}
@end

ConcreteHandler3类接口

代码如下:

#import "Handlers.h"

@interface ConcreteHandler3 :Handlers
@end

ConcreteHandler3类实现

代码如下:

#import "ConcreteHandler3.h"

@implementation ConcreteHandler3
-(void)HandleRequest:(int)request{
    if (request >=20 && request <30) {
        NSLog(@"ConcreteHandler3处理%d", request);
    }
    else if (mySuccessor !=nil) {
        [mySuccessor HandleRequest:request];
    }
}
@end

Main方法调用

代码如下:

#import <Foundation/Foundation.h>

int main(int argc,const char * argv[])
{
    @autoreleasepool{
        Handlers *h1 = [[ConcreteHandler1 alloc]init];
        Handlers *h2 = [[ConcreteHandler2 alloc]init];
        Handlers *h3 = [[ConcreteHandler3 alloc]init];
        [h1 SetSuccessor:h2];
        [h2 SetSuccessor:h3];
        int requests[] = {2,5,14,22,18,3,27,20};
        for (int i =0; i <8; i++) {
            [h1 HandleRequest:requests[i]];
        }
    }
    return 0;
}

好啦,代码展示完毕!收工!

小结
行为型模式是对在不同的对象之间划分责任和算法的抽象化,行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。通过行为型模式,可以更加清晰地划分类与对象的职责,并研究系统在运行时实例对象之间的交互。行为型模式可以分为类行为型模式和对象行为型模式两种。职责链模式可以避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,它是一种对象行为型模式。
在我们日常使用中,我们或许直接接触这方面的机会不多,但是,如果你认真有研究过程序的一场处理机制,那么你就能够发现这种处理机制正是采用职责链的方式处理程序中抛出的异常错误的。
在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
职责链模式的主要优点在于可以降低系统的耦合度,简化对象的相互连接,同时增强给对象指派职责的灵活性,增加新的请求处理类也很方便;其主要缺点在于不能保证请求一定被接收,且对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。

优点:
降低耦合度。
可简化对象的相互连接。
增强给对象指派职责的灵活性。
增加新的请求处理类很方便。

缺点:
不能保证请求一定被接收。
系统性能将受到一定影响,而且在进行代码调试时不太方便(可能会造成循环调用)。

(0)

相关推荐

  • iOS App设计模式开发中策略模式的实现示例

    这次介绍一下策略模式(Strategy Pattern),相比之下是一种比较简单的模式.它也叫政策模式(Policy Pattern). 策略模式使用的就是面向对象的继承和多态机制,其他的没有什么玄机.策略模式适合使用在: 1. 多个类只有在算法或行为上稍有不同的场景. 2. 算法需要自由切换的场景. 3. 需要屏蔽算法规则的场景. 使用策略模式当然也有需要注意的地方,那么就是策略类不要太多,如果一个策略家族的具体策略数量超过4个,则需要考虑混合模式,解决策略类膨胀和对外暴露问题.在实际项目中,

  • 实例解析设计模式中的外观模式在iOS App开发中的运用

    外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义 一个高层接口,这个接口使得这一子系统更加容易使用. 下面给大家展示一下类的结构图,想必大家一看就明白了: 其实这个模式中,没有类与类之间的继承关系,只是进行了简单的类引用,统一了对外的接口而已.看起来是不是很简单?废话不多说了,下面简单向大家展示一下代码吧! 注意:本文所有代码均在ARC环境下编译通过. SubSystemOne类接口 复制代码 代码如下: #import <Foundation/Foundation.

  • 详解iOS App设计模式开发中对于享元模式的运用

    享元模式的概念 在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能.共享的对象只能提供某些内在的信息,而不能用来识别对象.专门用于设计可共享对象的一种设计模式叫做享元模式(Flyweight pattern). 实现享元模式需要两个关键组件,通常是可共享的享元对象和保存他们的池.某种中央对象维护这个池,并从它返回适当的实例. 运用共享技术有效地支持大量细粒度的对象. 公共交通(如公共汽车)已有一百多年的历史了.大量去往相同方向的乘客可以分担保有和经营车辆(如公共汽车)的费用.公共汽车有

  • 设计模式开发中的备忘录模式在iOS应用开发中的运用实例

    何为备忘录模式? 在响应某些事件时,应用程序需要保存自身的状态,比如当用户保存文档或程序退出时.例如,游戏退出之前,可能需要保存当前会话的状态,如游戏等级.敌人数量.可用武器的种类等.游戏再次打开时,玩家可以从离开的地方接着玩.很多时候,保存程序的状态真的不需要什么特别巧妙的方法.任何简单有效的方法都可以,但是同时,保存信息应该只对原始程序有意义.原始程序应该是能够解码它所保存文档中的信息的唯一实体.这就是备忘录模式应用于游戏.文字处理等程序的软件设计中的方式,这些程序需要保存当前上下文的复杂状

  • iOS App设计模式开发中对建造者模式的运用实例

    定义          "将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现". 看这个概念,可能感觉很是抽象,能看懂但是不知道有什么用.我们打一个比方来理解上面的定义.打比方之前,咱们先来聊聊这个设计模式是干什么用的?我们为什么要用这个模式呢?建造者模式负责将构建复杂对象的过程和它的部件解耦,也就是过程和部件的解耦.比如说汽车,是一个很复杂的对象,它有很多的部件,车轮.发动机.座椅.车门.油箱等等:它的组装过程也很复杂(需要专业人士按步骤进行装配),建造者模式就

  • 深入解析设计模式中的装饰器模式在iOS应用开发中的实现

    装饰器模式可以在不修改代码的情况下灵活的为一对象添加行为和职责.当你要修改一个被其它类包含的类的行为时,它可以代替子类化方法. 一.基本实现 下面我把类的结构图向大家展示如下: 让我们简单分析一下上面的结构图,Component是定义一个对象接口,可以给这些对象动态地添加职责.ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责.Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需

  • 解析iOS应用开发中对设计模式中的抽象工厂模式的实现

    概述 抽象工厂模式是对象的创建模式,它是工厂方法模式的进一步推广. 假设一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构.那么为了将消费这些产品对象的责任和创建这些产品对象的责任分割开来,可以引进抽象工厂模式.这样的话,消费产品的一方不需要直接参与产品的创建工作,而只需要向一个公用的工厂接口请求所需要的产品. 通过使用抽象工厂模式,可以处理具有相同(或者相似)等级结构中的多个产品族中的产品对象的创建问题.如下图所示: 根据产品角色的结构图,就不难给出工厂角色的结构设计图. 可以

  • iOS App设计模式开发中对迭代器模式的使用示例

    何为迭代器模式? 迭代器提供了一种顺序访问集合对象中元素的方法,而无需暴漏结构的底层表示和细节.遍历集合中元素的职能从集合本身转移到迭代器对象.迭代器定义了一个用于访问集合元素并记录当前元素的接口.不同的迭代器可以执行不同的策略. 例子 说了这么多,下面给大家展示一下类关系图. 上图中Client的右边是迭代器,左边是具体迭代的类型,在迭代器内部对具体需要迭代的类型进行了引用,还算不难理解吧,呵呵.其实,看起来是为了对具体类型进行解耦.好啦,下面给出具体的代码实现,简单的模拟了迭代器模式. 注意

  • 详解iOS应用开发中使用设计模式中的抽象工厂模式

    概述 我们知道简单工厂模式的优点是去除了客户端与具体产品的依赖,缺点是违反了"开放-关闭原则":工厂方法模式克服了简单工厂模式的缺点,将产品的创建工作放到具体的工厂类,每个工厂类负责生成一个产品.但是在实际应用中,一个工厂类只创建单个产品的情况很少,一般一个工厂类会负责创建一系列相关的产品,如果我们要设计这样的系统,工厂方法模式显然不能满足应用的需求,本章要介绍的抽象工厂模式,可以很好地解决一系列产品创建的问题. 定义 "提供一个创建一系列相关或相互依赖对象的接口,而无需指定

  • iOS App的设计模式开发中对State状态模式的运用

    1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对复杂状态的判断就显得"力不从心了".随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱.维护也会很麻烦.那么我就考虑只修改自身状态的模式. 例子1:按钮来控制一个电梯的状态,一个电梯开们,

随机推荐