首页 > 其他分享 >职责链模式 Chain of Resposibility

职责链模式 Chain of Resposibility

时间:2022-09-30 14:13:43浏览次数:55  
标签:Resposibility const 职责 Chain req 接受者 数据结构 Reqest 请求

“数据结构”模式

  • 常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问,是一种行之有效的解决方案。
  • 典型模式
    1.Composite
    2·Iterator // 现在有点过时了?
    3·Chain of Resposibility // 现在有点过时了?

动机(Motivation)

  • 在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。
  • 如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。

模式定义

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链(链表,这也就是这里被定义为数据结构模式的原因),并沿着这条链传递请求,直到有一个对象处理它为止。——《设计模式》GoF

代码示例

#include <iostream>
#include <string>

using namespace std;

enum class RequestType
{
    REQ_HANDLER1,
    REQ_HANDLER2,
    REQ_HANDLER3
};

class Reqest
{
    string description;
    RequestType reqType;
public:
    Reqest(const string & desc, RequestType type) : description(desc), reqType(type) {}
    RequestType getReqType() const { return reqType; }
    const string& getDescription() const { return description; }
};

class ChainHandler {
    ChainHandler *nextChain;
    void sendReqestToNextHandler(const Reqest & req)
    {
        if (nextChain != nullptr)
            nextChain->handle(req);
    }
protected:
    virtual bool canHandleRequest(const Reqest & req) = 0;
    virtual void processRequest(const Reqest & req) = 0;
public:
    ChainHandler() { nextChain = nullptr; }
    void setNextChain(ChainHandler *next) { nextChain = next; }

    void handle(const Reqest & req)
    {
        if (canHandleRequest(req))
            processRequest(req);
        else
            sendReqestToNextHandler(req);
    }
};


class Handler1 : public ChainHandler {
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER1;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler1 is handle reqest: " << req.getDescription() << endl;
    }
};

class Handler2 : public ChainHandler {
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER2;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler2 is handle reqest: " << req.getDescription() << endl;
    }
};

class Handler3 : public ChainHandler {
protected:
    bool canHandleRequest(const Reqest & req) override
    {
        return req.getReqType() == RequestType::REQ_HANDLER3;
    }
    void processRequest(const Reqest & req) override
    {
        cout << "Handler3 is handle reqest: " << req.getDescription() << endl;
    }
};


int main() {
    Handler1 h1;
    Handler2 h2;
    Handler3 h3;
    h1.setNextChain(&h2);
    h2.setNextChain(&h3);

    Reqest req("process task ... ", RequestType::REQ_HANDLER3); // 希望哪一个来处理。
    h1.handle(req);

    getchar();
    return 0;
}

输出:

Handler3 is handle reqest: process task ...

类图

// 现在很多人都不认为它是一个设计模式_。觉得它只是单纯的一个数据结构。设计模式的思想是 94 年提出的,现在一直在进步。

要点总结

  • Chain of Responsibility 模式的应用场合在于“一个请求可能有多个接受者,但是最后真正的接受者只有一个”,这时候请求发送者与接受者的耦合有可能出现“变化脆弱”的症状,职责链的目的就是将二者解耦,从而更好地应对变化。
  • 应用了Chain of Responsibility模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。
  • 如果请求传递到职责链的末尾仍得不到处理,应该有一个合理的缺省机制。这也是每一个接受对象的责任,而不是发出请求的对象的责任。




参考:GeekBand

标签:Resposibility,const,职责,Chain,req,接受者,数据结构,Reqest,请求
From: https://www.cnblogs.com/huvjie/p/16744665.html

相关文章

  • Filter、FilterChain、FilterConfig 介绍
    一、Filter的基本工作原理1、Filter程序是一个实现了特殊接口的Java类,与Servlet类似,也是由Servlet容器进行调用和执行的。2、当在web.xml注册了一个Filter......
  • 面向对象的7种设计原则(1)-单一职责原则
    永远不要让一个类存在多个改变的理由。单一原则表明,如果你有多个原因去改变一个类,那么应该把这些引起变化的原因分离开,把这个类分成多个类,每个类只负责处理一种改变。当......
  • 图像算法工程师和图像算法测试工程师工作职责【杭州多测师】【杭州多测师_王sir】
    工作职责1、设计图像测试方案,协助开发进行图像效果调试与验证;2、撰写图像测试报告;3、进行图像评测与竞品分析;4、根据需求进行测试图像样本采集与筛选。5、熟悉常见图像算法......
  • Typescript类型体操 - Chainable Options
    题目中文在JavaScript中我们经常会使用可串联(Chainable/Pipeline)的函数构造一个对象,但在TypeScript中,你能合理的给它赋上类型吗?在这个挑战中,你可以使用任意你喜欢的......
  • CF1511 F. Chainword / G. Chips on a Board
    F太屑了,没写如果直接暴力记矩阵的话是40*40=1600边长,显然不行发现如果上下都没有匹配结束,则后面的字母是唯一确定的(按位比较,不同则无解)设f[i,x]表示串长i,一边匹配到x,则......
  • maven打包报错:Cannot find matching toolchain definitions for the following toolch
      报错信息: [ERROR]Failedtoexecutegoalorg.apache.maven.plugins:maven-toolchains-plugin:1.1:toolchain(default)onprojectmyfile:Cannotfindmatchi......
  • Apache Maven ToolChains的使用
    ApacheMavenToolChains的使用  简介Toolchains的介绍Toolchains的例子Toolchains支持总结简介Maven是java中非常有用和常用的构建工具,基本上现在大型的java项目都是M......
  • HDU3487 Play With Chain
    题目链接  题目大意就是要我们对一个区间执行区间翻转和整体移动区间的操作。  思路:将一个区间分裂出来再移动到另一个节点的后面,可以用\(fhq-treap\)来将这一个子树......
  • gym-101667K Untangling Chain
    UntanglingChain构造显然对于一条线段来说,走到头只有左右两边可以选择,换句话说,第一次是横着走,第二次是竖着走,因此可以构造一个走法,让他每次都突破自身走过路径的四个边(......
  • java设计模式之职责链模式(二)
    职责链模式的一个变种如下,执行某一个handler,用当前handler是否执行成功判断是否要执行下一个handler,首先我们定义一个抽象handler类,如果当前handler执行不成功,且还有下一......