C++设计模式 - 职责链模式(Chain of Resposibility)
数据结构模式
- 常常有一-些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问,是一种行之有效的解决方案。
典型模式
Chain of Resposibility
动机( Motivation )
- 在软件构建过程中, -个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。
- 如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求 ,从而使两者解耦。
模式定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
结构

要点总结
- Chain of Responsibility模式的应用场合在于“一个请求可能有,多个接受者,但是最后真正的接受者只有一个”, 这时候请求发送者与接受者的耦合有可能出现“变化脆弱”的症状,职责链的目的就是将二者解耦,从而更好地应对变化。
- 应用了Chain of Responsibility模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。
- 如果请求传递到职责链的末尾仍得不到处理,应该有一个合理的,缺省机制。这也是每一个接受对象的责任,而不是发出请求的对象的责任。
cpp
#include<iostream>
#include<string>
enum class RequestType
{
REQ_HANDLER1,
REQ_HANDLER2,
REQ_HANDLER3
};
class Reqest
{
public:
Reqest(const std::string& desc, RequestType type) :description(desc), reqType(type) {}
RequestType getReqType()const { return reqType; }
const std::string& getDescription()const { return description; }
private:
std::string description;
RequestType reqType;
};
class ChainHandler
{
public:
ChainHandler() :nextChain(nullptr) {}
void setNextChain(ChainHandler* next) { nextChain = next; }
void handle(const Reqest& req)
{
if (this->canHandleRequest(req))
{
this->processRequest(req);
}
else
{
this->sendReqestToNextHandler(req);
}
}
protected:
virtual bool canHandleRequest(const Reqest&) = 0;
virtual void processRequest(const Reqest&) = 0;
private:
void sendReqestToNextHandler(const Reqest& req)
{
if (nextChain != nullptr)
{
nextChain->handle(req);
}
}
private:
ChainHandler* nextChain;
};
class Handler1 :public ChainHandler
{
public:
virtual bool canHandleRequest(const Reqest& req)
{
return req.getReqType() == RequestType::REQ_HANDLER1;
}
virtual void processRequest(const Reqest& req)
{
std::cout << "Handler1 is handle reqest: " << req.getDescription() << std::endl;
}
};
class Handler2 : public ChainHandler {
protected:
bool canHandleRequest(const Reqest& req) override
{
return req.getReqType() == RequestType::REQ_HANDLER2;
}
void processRequest(const Reqest& req) override
{
std::cout << "Handler2 is handle reqest: " << req.getDescription() << std::endl;
}
};
class Handler3 : public ChainHandler {
protected:
bool canHandleRequest(const Reqest& req) override
{
return req.getReqType() == RequestType::REQ_HANDLER3;
}
void processRequest(const Reqest& req) override
{
std::cout << "Handler3 is handle reqest: " << reqc.getDescription() << std::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);
return 0;
}
C++设计模式 - 职责链模式(Chain of Resposibility)的更多相关文章
- 设计模式:职责链模式(Chain of Responsibility)
去年参加校招要到长沙来,这个对于我来说不是特别喜欢(但又必须的来,谁叫咱不是985.211的娃呢),但是对于某些人来说就是福音了.大四还有课,而且学校抓的比较严,所以对于那些想翘课的人来说这个是最好不 ...
- C#设计模式——职责链模式(Chain Of Responsibility Pattern)
一.概述 在软件开发中,某一个对象的请求可能会被多个对象处理,但每次最多只有一个对象处理该请求,对这类问题如果显示指定请求的处理对象,那么势必会造成请求与处理的紧耦合,为了将请求与处理解耦,我们可以使 ...
- 大话设计模式--职责连模式 Chain of Resposibility -- C++实现实例
1. 职责链模式: 使多个对象都有机会处理请求,从而避免请求发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它. 当客户提交一个请求时,请求是沿着链传递直 ...
- 深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)
模式动机 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传 ...
- atitit.设计模式(1)--—职责链模式(chain of responsibility)最佳实践O7 日期转换
atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 可以选择的模式: 表格模式,责任链模式 1 3 ...
- 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...
- 责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)
责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这 ...
- 设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就 ...
- JAVA 设计模式 职责链模式
用途 职责链模式 (Chain Of Responsibility) 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系. 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个 ...
- 17. 星际争霸之php设计模式--职责链模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
随机推荐
- java使用Timer定时器在指定时间执行程序
下面是一个利用Timer定时器在每天指定时间执行批处理程序的例子. 有关 java.util.Timer 详细知识请参考API. 值得注意的一点是Timer是单线程顺序执行多个任务的. package ...
- CentOS8安装Geant4笔记(二):CentOS8安装Qt5.15.2并测试运行环境
前言 在服务器CentOs8.2上安装geant4软件,但是运行不起来,所以本节开始主要是安装qt,测试qt基本功能. 要点 添加qt环境到系统环境中,是geant4启动qt的必要条件. ...
- 解决pip install时出现的Could not fetch URL https://pypi.org/simple/pip/问题
打开windows的我的电脑,在最上方目录栏输入%APPDATA%,回车,接着会定位到一个新的目录, 目录路径为C:\Users\Administrator\AppData\Roaming,在这个目录 ...
- java+mysql学生信息管理系统
实现:mysql+eclipse(idea设置之后也可运行)+jdk8 功能: 管理员:管理登+管理员注册 学生:添加学生信息+删除学生信息+修改学生信息+查询学生信息+学生列表展示 界面展示: 详情 ...
- Django重点
Django 简述python三大主流web框架 """ django 大而全,类似于航空母舰 但是有时候过于笨重 flask 小而精,类似于游骑兵(单行代码就可以起一个 ...
- Lua调试函数 debug.getinfo() namewhat详解
Lua调试的时候会用到debug.getinfo()函数,what的值文档给了解释: "Lua" : Lua function "C" : C function ...
- 【Azure 应用服务】Azure Function Python函数中,如何获取Event Hub Trigger的消息Event所属于的PartitionID呢?
问题描述 在通过Azure Function消费Event Hub中的消息时,我们从Function 的 Trigger Details 日志中,可以获得当前Funciton中处理的消息是哪一个分区( ...
- 【Azure 应用服务】在App Service中调用外部服务API时需要携带客户端证书,而多次调用的情况下会出现WindowsCryptographicException Keyset does not exist异常
问题描述 在App Service中调用外部服务API时需要携带客户端证书,而多次调用的情况下会出现WindowsCryptographicException Keyset does not exis ...
- [学习笔记]在Linux中使用源码编译的方式安装Nginx
准备工作 准备nginx源码包: http://nginx.org/en/download.html 准备相关的依赖包以及环境: gzip 模块需要 zlib 库 http://www.zlib. ...
- 新博客 VuejsDev.com 用于梳理知识点
新博客 VuejsDev.com 用于梳理知识点 https://www.vuejsdev.com/ 后期没有精力发布了,迁移到博客园了,防止服务器到期~ [VueJsDev] 目录列表 https: ...