【设计模式】责任链模式

1、定义

1.1 标准定义

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。)

1.2 通用类图

责任链模式的核心在“链”上, “链”是由多个处理者ConcreteHandler组成的。

2、实现

2.1 类图

抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。

具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

2.2 代码

2.2.1 Hander类

// Chander.h

#include <iostream>

class CResponse;
class CRequest;

class CHander
{
public:
    CHander();
    ~CHander();

    CResponse  * mopHandleMessage(CRequest  *opRequest);

    void mvSetNext(CHander  *opHander);

protected:
    virtual std::string msGetEcho() = 0;

protected:
    CHander *mopNexthander;
    int          miLevel;
};

//  构造三个链成员
class CHander_1 : public CHander
{
public:
    CHander_1();
    ~CHander_1();

    virtual std::string msGetEcho();
};

class CHander_2 : public CHander
{
public:
    CHander_2();
    ~CHander_2();

    virtual std::string msGetEcho();
};

class CHander_3 : public CHander
{
public:
    CHander_3();
    ~CHander_3();

    virtual std::string msGetEcho();
};

// 请求
class CRequest
{
public:
    int miNumber;
};

// 反馈
class CResponse
{
public:
    CResponse(const std::string &sResponse);
    ~CResponse();

    // 获取请求处理结果
    std::string msGetResponse();

private:
    std::string msResponse;
};
// Chander.cpp

#include "CHander.h"

// CHander
CHander::CHander() {};

CHander::~CHander(){};

CResponse  *CHander::mopHandleMessage(CRequest *opRequest)
{
    if (miLevel == opRequest->miNumber)
    {
        return new CResponse(msGetEcho());
    }
    else
    {
        if (NULL != mopNexthander)
        {
            return mopNexthander->mopHandleMessage(opRequest);
        }
    }

    return new CResponse("No Handle.");
}

void CHander::mvSetNext(CHander  *opHander)
{
    this->mopNexthander = opHander;
}

// CHander_1
CHander_1::CHander_1()
{
    // 定义级别
    miLevel = 1;
    mopNexthander = NULL;
}

CHander_1::~CHander_1(){};

std::string CHander_1::msGetEcho()
{
    return "CHander_1 message.\n";
}

// CHander_2
CHander_2::CHander_2()
{
    // 定义级别
    miLevel = 2;
    mopNexthander = NULL;
}

CHander_2::~CHander_2(){};

std::string CHander_2::msGetEcho()
{
    return "CHander_2 message.\n";
}

// CHander_3
CHander_3::CHander_3()
{
    // 定义级别
    miLevel = 3;
    mopNexthander = NULL;
}

CHander_3::~CHander_3(){};

std::string CHander_3::msGetEcho()
{
    return "CHander_3 message.\n";
}

//CResponse
CResponse::CResponse(const std::string &sResponse) : msResponse(sResponse){}

CResponse::~CResponse(){};

std::string CResponse::msGetResponse()
{
    return msResponse;
}

2.2.3 调用

#include <iostream>
#include "CHander.h"

using namespace std;

int main()
{
    CHander *opHander1 = new CHander_1;
    CHander *opHander2 = new CHander_2;
    CHander *opHander3 = new CHander_3;

    //构造执行链
    opHander1->mvSetNext(opHander2);
    opHander2->mvSetNext(opHander3);

    CRequest *opRequest = new CRequest;
    opRequest->miNumber = 2;
    CResponse *opResponse = opHander1->mopHandleMessage(opRequest);
    std::cout << opResponse->msGetResponse().c_str() << endl;
    delete opResponse;
    opResponse = NULL;

    opRequest->miNumber = 1;
    opResponse = opHander1->mopHandleMessage(opRequest);
    std::cout << opResponse->msGetResponse().c_str() << endl;
    delete opResponse;
    opResponse = NULL;

    opRequest->miNumber = 4;
    opResponse = opHander1->mopHandleMessage(opRequest);
    std::cout << opResponse->msGetResponse().c_str() << endl;
    delete opResponse;
    opResponse = NULL;

    delete opHander1;
    delete opHander2;
    delete opHander3;

    return 0;
}

2.2.3 执行结果

3、优缺点

3.1 优点

责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌。两者解耦,提高系统的灵活性。

3.2 缺点

责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题。二是调试不很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。

3.3 注意

链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。

3.4 总结

在例子和通用源码中CHandler是抽象类, 融合了模板方法模式, 每个实现类只要实现 echo方法处理请求和设置自身级别, 想想单一职责原则和迪米特法则吧, 通过融合模板方法模式, 各个实现类只要关注的自己业务逻辑就成了, 至于说什么事要自己处理, 那就让父类去决定好了, 也就是说父类实现了请求传递的功能, 子类实现请求的处理, 符合单一职责原则, 各个实现类只完成一个动作或逻辑,也就是只有一个原因引起类的改变,在使用的时候用这种方法, 好处是非常明显的了,子类的实现非常简单,责任链的建立也是非常灵活的。

责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者, 最终会返回一个处理结果( 当然也可以不做任何处理), 为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心,同时责任链模式也可以作为一种补救模式来使用。举个简单例子,如项目开发的时候, 需求确认是这样的:一个请求(如银行客户存款的币种),一个处理者( 只处理人民币),但是随着业务的发展(改革开放了嘛,还要处理美元、日元等),处理者的数量和类型都有所增, 那这时候就可以在第一个处理者后面建立一个链,也就是责任链来处理请求,如果是人民币,好,还是第一个业务逻辑来处理;如果是美元,好,传递到第二个业务逻辑来处理;日元、 欧元……这些都不用在对原有的业务逻辑产生很大改变, 通过扩展实现类就可以很好
地解决这些需求变更的问题。

时间: 2024-11-17 06:39:59

【设计模式】责任链模式的相关文章

java 设计模式 -- 责任链模式

设计模式 – 责任链模式 介绍: 责任链模式是一种动态行为模式,有多个对象,每一个对象分别拥有其下家的引用.连起来形成一条链.待处理对象则传到此链上,在此链进行传递,且待处理对象并不知道此会被链上的哪个对象处理,这使得我们能够动态的添加链上的对象而且分配责任. 纯责任链和非纯责任链 责任链分为两种.纯责任链和非纯责任链. 纯责任链是待处理对象request在处理对象handler链上传递,每一个处理对象handler处理request的一部分,到终于处理完毕.非纯责任链则是待处理对象reques

[设计模式] 责任链模式之变种 - 责任链子

今天看到 wikipedia 的责任链模式,好奇之下搜寻相关文章,此文章主要参考 91大的 [.NET]重构之路系列v11 –用责任链模式打破讨厌的switch case 的变种作法,所以跟原本的责任链模式的设计思路不太相同,但结果相同, 所以阅读前,建议先看完91大的文章后,在来看这篇会比较能感觉出差异. ?这边先引用91大文章结尾结论中的补充来复习一下责任链的重点, 20120415 补充:责任链的用意在于把每个角色的职责分清楚,每个对象只需要做好自己的事,透过责任链的方式来组合,并完成使用

24天学会设计模式------责任链模式

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka/article/details/43210027 一.责任链模式(Chain of Responsibility Pattern) 1.简介 从名字上大概也能猜出这个模式的大概模样--系统中将会存在多个有类似处理能力的对象.当一个请求触发后,请求将在这些对象组成的链条中传递,直到找到最合适的"责任"对象,并进行处理.<设计模式>中给它的定义如下:使多个对象都有机会处理请

Java与设计模式-责任链模式

责任链模式属于行为型设计模式之一,怎么理解责任链?责任链是可以理解成数个对象首尾连接而成,每一个节点就是一个对象,每个对象对应不同的处理逻辑,直至有一个对象响应处理请求结束.这一种模式成为责任链模式. 生活中可以找到责任链模式的原型吗?这种例子很多,比如你要去买房子,首先是销售人员(对象1)接待你,你说想要百分之3的折扣,没问题,这时销售人员就有打百分之三折扣的权限,销售人员(对象1)进行处理.这时来了一个土豪,说要买10套,要百分之五的折扣,销售人员(对象1)没有百分之五折扣的权限,必须要想上

我的Java设计模式-责任链模式

今天来说说程序员小猿和产品就关于需求发生的故事.前不久,小猿收到了产品的需求. 产品经理:小猿,为了迎合大众屌丝用户的口味,我们要放一张图,要露点的. 小猿:......露点?你大爷的,让身为正义与纯洁化身的我做这种需求,还露点. 产品经理:误会误会,是放一张暴露一点点的,尺寸不大. 小猿:尼玛~能说清楚些吗,需求模棱两可的.不干,我要上报boss. 产品经理也一阵无语,这豆丁的事还上报boss.话说这上报也得走程序是吧,技术经理就不干了,"凭什么要跳过我,得经过我才能到boss".咦

设计模式-责任链模式在实际项目中的使用

最近一次迭代,参与了公司数据应用平台的开发,其中负责的一块功能早早的就完成了代码的编写工作,即将进入测试阶段,因为有时间思考和总结代码编写中遇到的难题,便想着将代码做一次重构:其中优化的一个功能就是关于数据平台敏感字段的收集 功能描述:数据平台敏感字段的收集: 提供 service 方法,查询是否需要扫描表做触发式收集,指定具体实例与库的表,随机取 N 行(1~max(id) 之间):a.对每一行的每一个字段的值(取非 null 非空的值)做正则匹配 b. 对每一行的每一个字段的值看是否包含了敏

24种设计模式--责任链模式【Chain ofResponsibility Pattern】

中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父.既嫁从夫.夫死从子”,也就是说一个女性,在没有结婚的时候要听从于父亲,结了婚后听从于丈夫,丈夫死了还要听儿子的,举个例子来说,一个女的要出去逛街,同样这样的一个请求,在她没有出嫁前她必须征得父亲的同意,出嫁之后必须获得丈夫的许可,那丈夫死了怎么办?一般都是男的比女的死的早,还要问问儿子是否允许自己出去逛街,估计你下边马上要问要是没有儿子怎么办?请示小叔子.侄子等等,在父系社会中,妇女只占从属地位,现在想想中国的妇女还是比较悲惨的

设计模式 -- 责任链模式或者叫职责链模式(Chain of Responsibility(CoR))

什么是链?前后相连,一个连接下一个,其中包括多个节点,其实责任链模式也类似,他是多个对象之间相互关联,下一个对象的操作由上一个对象关联下来,上一个对象有个方法用于指向其他对象.职责链之间的前后关系是可以改变的,主要看上一节点主要指向哪个节点. android中事件分发就是责任链模式的具体表现: View的ontouchEvent返回值设置,如果为true,交个自己的消费事件的方法去处理,如果为false,则继续向下一个进行传递. 如何实现责任链模式: 比如责任链上有,A,B,C三个对象,如果A有

java设计模式--责任链模式

责任链模式:将能够处理同一类请求的对象连成一条链,如果不能处理则传递给链上的下一个对象. //请假对象 public class QingjiaRequest { private String name; private int days; private String reason; public QingjiaRequest(String name, int days, String reason) { this.name = name; this.days = days; this.rea

设计模式——责任链模式

责任链模式:将能够处理同一类请求的对象连成一条链所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求, 如果能则处理,如果不能则传递给链上的下一个对象.优点:将请求者和发送者解耦         简化对象的处理过程         可以通过改变链中的成员或成员的顺序来动态的新增或则删除责任. 缺点:不能保证请求一定会执行,可能或落到责任链之外. 不容易观察运行时的特征,处理请求的方法比较分散.实现方式:链表和非链表两种实现,但是使用集合和数组等非链表实现在实际开发中更方便更常用. 应用