设计模式之责任链模式(二): 实现方式

这篇具有很好参考价值的文章主要介绍了设计模式之责任链模式(二): 实现方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++设计模式专栏:

相关文章系列

设计模式之责任链模式(一)-CSDN博客

目录

1.引言

2.实现方式1

3.实现方式2

4.总结        


1.引言

        责任链设计模式(Chain of Responsibiliy DesignPattern)简称职责链模式。在GOF的《设计模式:可复用面向对象软件的基础》中,它是这样定义的:将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求;将这些接收对象串成一条链,并沿者这条链传递这个请求,直到链上的某个接收对象能够处理它为止(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 )。

        在职责链模式中,多个处理器(也就是定义中所说的“接收对象”)依次处理同一个请求。一个请求首先经过A处理器处理,然后,这个请求被传递给B处理器,B处理器处理完后再将其传递给C处理器,以此类推,形成一个链条。因为链条上的每个处理器各自承担各自职责,所以称为职责链模式。

        职责链模式有多种实现方式,这里介绍两种常用的。

2.实现方式1

        实现方式的代码如下所示。其中,Handler类是所有处理器类的抽象父类,handle()是抽象方法。每个具体的处理器类(HandlerA、HandlerB)的handle()函数的代码结构类似,如果某个处理器能够处理该请求,就不继续往下传递;如果它不能处理,则交由后面的处理器处理(也就是调用successor.handle())。HandlerChain类表示处理器链,从数据结构的角度来看,它就是一个记录了链头、链尾的链表。其中,记录链尾是为了方便添加处理器。

#pragma once
#include <memory>
#include <vector>

class IHandler
{
protected:
	IHandler* m_successor;
public:
	void setSuccessor(IHandler* successor) {
		m_successor = successor;
	}
	virtual void handle() = 0;
};

class HandlerA : public IHandler
{
public:
	//...
	//@override
	void handle() override {
		bool bHandle = false;
		//...
		if (!bHandle && m_successor) {
			m_successor->handle();
		}
		//...
	}
};

class HandlerB : public IHandler
{
public:
	//...
	//@override
	void handle() override {
		bool bHandle = false;
		//...
		if (!bHandle && m_successor) {
			m_successor->handle();
		}
		//...
	}
};

class HandlerChain {
private:
	IHandler* head = nullptr;
	IHandler* tail = nullptr;
public:
	void addHandler(IHandler* handler) {
		handler->setSuccessor(nullptr);
		if (head == nullptr) {
			head = handler;
			tail = handler;
			return;
		}
		tail->setSuccessor(handler);
		tail = handler;
	}
	void handle() {
		if (head != nullptr) {
			head->handle();
		}
	}
};

//使用举例
int main() {
	std::unique_ptr<IHandler> pHandleA(new HandlerA());
	std::unique_ptr<IHandler> pHandleB(new HandlerB());
	HandlerChain chain;

	chain.addHandler(pHandleA.get());
	chain.addHandler(pHandleB.get());

	chain.handle();

    return 1;
}

        实际上,上面的代码实现不够优雅,因为处理器类的handle()函数不仅包含自己的业务逻辑。还包含对下一个处理器的调用(对应代码中的successor.handle())。如果一个不熟悉这种代码结构的程序员想要在其中添加新的处理器类,那么很有可能忘记在handle()函数中调用successor.handle(),这就会导致代码出现bug。

设计模式之模板方法模式-CSDN博客

        针对这个问题,我们对代码进行重构,利用模版方法模式,将调用successor.handle()的逻辑从处理器中剥离出来,放到抽象父类中。这样,处理器类只需要实现自己的业务逻辑。重构之后的代码如下所示:

class IHandler
{
protected:
	IHandler* m_successor;
public:
	void setSuccessor(IHandler* successor) {
		m_successor = successor;
	}
	void handle() {
		bool bHandled = doHandle();
		if (!bHandled && m_successor) {
			m_successor->handle();
		}
	}
protected:
	virtual bool doHandle() = 0;
};

class HandlerA : public IHandler
{
protected:
	//...
	//@override
	bool doHandle() override {
		bool bHandle = false;
		//...
		return bHandle;
	}
};

class HandlerB : public IHandler
{
protected:
	//...
	//@override
	bool doHandle() override {
		bool bHandle = false;
		//...
		return bHandle;
	}
};

class HandlerChain {
private:
	IHandler* head = nullptr;
	IHandler* tail = nullptr;
public:
	void addHandler(IHandler* handler) {
		handler->setSuccessor(nullptr);
		if (head == nullptr) {
			head = handler;
			tail = handler;
			return;
		}
		tail->setSuccessor(handler);
		tail = handler;
	}
	void handle() {
		if (head != nullptr) {
			head->handle();
		}
	}
};

int  main() {
	std::unique_ptr<IHandler> pHandleA(new HandlerA());
	std::unique_ptr<IHandler> pHandleB(new HandlerB());
	HandlerChain chain;

	chain.addHandler(pHandleA.get());
	chain.addHandler(pHandleB.get());

	chain.handle();

    return 1;
}

3.实现方式2

        实现代码如下所示,这种实现方式更加简单,其中HandlerChain 类用数组而非链表来保存所有处理器类,并且在HandlerChain类的handle()函数中,依次调用每个处理器类的 handle()函数。

class IHandler
{
public:
	virtual bool handle() = 0;
};

class HandlerA : public IHandler
{
public:
	//...
	//@override
	bool handle() override {
		bool bHandle = false;
		//...
		return bHandle;
	}
};

class HandlerB : public IHandler
{
public:
	//...
	//@override
	bool handle() override {
		bool bHandle = false;
		//...
		return bHandle;
	}
};

class HandlerChain {
private:
	std::vector<IHandler*> m_vecHandler;
public:
	void addHandler(IHandler* handler) {
		m_vecHandler.push_back(handler);
	}
	void handle() {
		for (auto& it : m_vecHandler) {
			if (it->handle()) {
				break;
			}
		}
	}
};

int main() {
	std::unique_ptr<IHandler> pHandleA(new HandlerA());
	std::unique_ptr<IHandler> pHandleB(new HandlerB());
	HandlerChain chain;

	chain.addHandler(pHandleA.get());
	chain.addHandler(pHandleB.get());

	chain.handle();

    return 1;
}

        在GoF合著的《设计模式:可复用面向对象软件的基础》给出的职责链模式的定义中。如果处理器链上的某个处理器能够处理这个请求,就不会继续往下传递请求。实际上,职责链模式还有一种变体,那就是请求会被所有处理器都处理一遍,不存在中途终止的情况。这种变体也有两种实现方式: 用链表存储处理器类和用数组存储处理器类,与上面两种实现方式类似稍加修改即可。这里只给出用链表存储处理器类的实现方式,代码如下所示。对于用数组存储处理器类的实现方式,读者可对照上面的实现自行修改。

class IHandler
{
protected:
	IHandler* m_successor;
public:
	void setSuccessor(IHandler* successor) {
		m_successor = successor;
	}
	void handle() {
		doHandle();
		if (m_successor) {
			m_successor->handle();
		}
	}
protected:
	virtual void doHandle() = 0;
};

class HandlerA : public IHandler
{
protected:
	//...
	//...
	//@override
	void doHandle() override {
		//...
	}
};

class HandlerB : public IHandler
{
protected:
	//...
	//@override
	void doHandle() override {
		//...
	}
};

class HandlerChain {
private:
	IHandler* head = nullptr;
	IHandler* tail = nullptr;
public:
	void addHandler(IHandler* handler) {
		handler->setSuccessor(nullptr);
		if (head == nullptr) {
			head = handler;
			tail = handler;
			return;
		}
		tail->setSuccessor(handler);
		tail = handler;
	}
	void handle() {
		if (head != nullptr) {
			head->handle();
		}
	}
};

int main() {
	std::unique_ptr<IHandler> pHandleA(new HandlerA());
	std::unique_ptr<IHandler> pHandleB(new HandlerB());
	HandlerChain chain;

	chain.addHandler(pHandleA.get());
	chain.addHandler(pHandleB.get());

	chain.handle();

    return 1;
}

4.总结        

        尽管我们给出了典型的职责链模式的代码实现,但在实际的开发中,我们还是要具体问题具体对待,因为职责链模式的代码实现会根据需求的不同而有所变化。实际上,这一点对于有设计模式都适用。文章来源地址https://www.toymoban.com/news/detail-859353.html

到了这里,关于设计模式之责任链模式(二): 实现方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式——责任链模式

    使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有对象处理它为止。 优点 能将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦提高系

    2024年02月15日
    浏览(41)
  • 设计模式:责任链模式

    责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象按照顺序处理请求,直到其中一个对象能够处理该请求为止。责任链模式将请求发送者和接收者解耦,使得多个对象都有机会处理请求,同时避免了请求发送者与接收者之间的直接耦合关系。 在

    2024年02月07日
    浏览(43)
  • 《设计模式》责任链模式

    定义 : 责任链模式将链中每一个节点都看成一个对象,并且将这些节点对象连成一条链,请求会沿着这条链进行传递,直到有对象处理它为止,这使得多个对象都有机会接收请求,避免了请求发送者和接收者之间的耦合。 属于 行为型 设计模式。 责任链模式的角色组成 :

    2024年02月13日
    浏览(43)
  • 设计模式——22. 责任链模式

    责任链模式是一种行为设计模式,它允许你创建一个对象链,每个对象都包含了请求的一部分处理逻辑,并且请求按照链的顺序依次传递,直到有一个对象处理它为止。责任链模式通常用于将一个请求从发送者传递给多个接收者,直到有一个接收者处理请求为止。 责任链模式

    2024年02月07日
    浏览(38)
  • 面试设计模式-责任链模式

    在进行请假申请,财务报销申请,需要走部门领导审批,技术总监审批,大领导审批等判断环节。存在请求方和接收方耦合性太强,代码会比较臃肿,不利于扩展和维护。 针对上面,使用责任链模式,将请求方和接收方的业务进行解耦, 客户端发送一个请求,由一个抽象的

    2024年02月09日
    浏览(41)
  • 设计模式之责任链模式

    责任链设计模式是一种行为设计模式,它允许你创建一个对象链。请求从链的一端进入,并沿着链的路径依次经过各个对象,直至找到合适的处理者。每个对象都决定是否要处理该请求或将其传递给链中的下一个对象。 1.1 核心概念 Handler(处理者):每个处理者对象包含了处

    2024年02月05日
    浏览(47)
  • 设计模式详解-责任链模式

    类型:行为型模式 实现原理:为请求创建了一个接收者对象的链。对请求的发送者和接收者进行解耦,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。 作用:避免请求发送者与接收者耦合在一

    2024年02月12日
    浏览(40)
  • 说说设计模式~责任链模式

    回到目录 它是一种设计模块,主要将操作流程与具体操作解耦,让每个操作都可以设置自己的操作流程,这对于工作流应用是一个不错的选择! 下面是官方标准的定义:责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一

    2024年02月11日
    浏览(38)
  • 设计模式07-责任链模式

    责任链模式属于行为设计模式,常见的过滤器链就是使用责任链模式设计的。 Q:假设有一个闯关游戏,共三关,每一关达到通过条件后才能进入下一关,使用java实现。 A:针对这个问题,按照朴素的想法,我们可以定义三个类,分别是第一关、第二关、第三关,客户端启动

    2024年02月16日
    浏览(41)
  • 重温设计模式 --- 责任链模式

    责任链模式 是一种行为型设计模式,它通过一条由多个处理器组成的链来处理请求,每个处理器都有机会处理请求,如果一个处理器不能处理该请求,它会将请求传递给下一个处理器,直到请求被处理为止。 在实际应用中,责任链模式常用于处理请求的分发、事件处理等场

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包