音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

iOS应用设计模式开发中职责链(责任链)模式的实现解析
日期:2016-03-30 17:39:48   来源:脚本之家

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

原理结构

2016330173610369.png (504×398)

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

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

下面给出类结构图。

2016330173647539.jpg (500×291)

从上图可以看出,当客户提交一个请求时,请求是沿链传递直至有一个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;
}


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

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

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

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

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    Windows系统Linux系统苹果MACAndroidiOS系统鸿蒙系统