码迷,mamicode.com
首页 > 其他好文 > 详细

【设计模式】责任链模式

时间:2017-07-28 00:56:28      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:ges   抽象类   类型   构造   lin   else   产生   using   pass   

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

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

【设计模式】责任链模式

标签:ges   抽象类   类型   构造   lin   else   产生   using   pass   

原文地址:http://www.cnblogs.com/ChinaHook/p/7248075.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!