设计模式14- Chain of Responsibility Method 责任链设计模式
1.定义
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式。它通过把请求从一个对象传到链条中的下一个对象的方式,直到请求被处理完毕,以实现解耦。
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它使得多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。该模式把这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2.内涵
核心角色:
- Handler(抽象处理者): 定义一个处理请求的接口,并实现后续链的相关方法。
- ConcreteHandler(具体处理者): 具体的处理者对象,处理它所负责的请求,并确定该请求是否需要传递给下一个处理者。
- Client(请求发送者): 提出请求的客户端对象。
工作原理:
- 客户端发送请求;
- 请求沿着处理者链向下传递,直到有一个具体的处理者能够处理该请求;
- 每个处理者决定是否处理该请求或将其传递给链中的下一个处理者;
- 当请求被处理或到达链的末端而无人处理时,请求处理过程结束。
3.使用示例
cpp
#include <iostream>
#include <string>
// Handler Interface
class AuthenticationHandler {
public:
virtual void
setNextHandler(AuthenticationHandler* handler)
= 0;
virtual void handleRequest(const std::string& request)
= 0;
};
// Concrete Handlers
class UsernamePasswordHandler
: public AuthenticationHandler {
private:
AuthenticationHandler* nextHandler;
public:
void
setNextHandler(AuthenticationHandler* handler) override
{
nextHandler = handler;
}
void handleRequest(const std::string& request) override
{
if (request == "username_password") {
std::cout << "Authenticated using username and "
"password."
<< std::endl;
}
else if (nextHandler != nullptr) {
nextHandler>handleRequest(request);
}
else {
std::cout << "Invalid authentication method."
<< std::endl;
}
}
};
class OAuthHandler : public AuthenticationHandler {
private:
AuthenticationHandler* nextHandler;
public:
void
setNextHandler(AuthenticationHandler* handler) override
{
nextHandler = handler;
}
void handleRequest(const std::string& request) override
{
if (request == "oauth_token") {
std::cout << "Authenticated using OAuth token."
<< std::endl;
}
else if (nextHandler != nullptr) {
nextHandler>handleRequest(request);
}
else {
std::cout << "Invalid authentication method."
<< std::endl;
}
}
};
// Client
int main()
{
AuthenticationHandler* usernamePasswordHandler
= new UsernamePasswordHandler();
AuthenticationHandler* oauthHandler
= new OAuthHandler();
// Set up the chain
usernamePasswordHandler>setNextHandler(oauthHandler);
// Handling authentication requests
usernamePasswordHandler>handleRequest("oauth_token");
usernamePasswordHandler>handleRequest(
"username_password");
usernamePasswordHandler>handleRequest(
"invalid_method");
delete usernamePasswordHandler;
delete oauthHandler;
return 0;
}
4.注意事项
使用责任链模式时需要注意以下几个方面:
- 责任链的构造:
需要确定责任链中各个处理者的顺序,并构建好责任链结构。顺序安排不当可能导致请求无法得到合适的处理。
处理者之间的引用关系要合理,避免循环引用等问题。
- 请求传递与终止:
需要明确处理者何时应该处理请求,何时应该将请求传递给下一个处理者。
应该有明确的终止条件,避免请求无休止地在责任链中传递下去。
- 处理者的实现:
每个处理者需要实现自己的请求处理逻辑,并明确哪些请求可以处理,哪些需要传递。
处理者需要合理使用前置/后置条件,避免处理能力过于集中或分散。
- 性能问题:
过长的责任链可能会影响性能,需要权衡责任链的长度。
可以考虑使用缓存等技术优化责任链的性能。
- 异常处理:
需要考虑当某个处理者出现异常时,如何确保请求能被后续处理者正确处理。
- 扩展性:
责任链模式应该具有良好的扩展性,便于在不修改现有代码的情况下增加新的处理者。
总之,在使用责任链模式时,需要充分考虑责任链的构造、请求的传递与终止、各处理者的实现逻辑、性能问题、异常处理以及扩展性等方面,以确保模式的正确应用。
5.最佳实践
责任链模式的最佳实践,主要包括以下几个方面:
明确职责划分:
各个处理者需要清楚自己的职责范围,避免出现处理能力重叠或职责模糊的情况。
可以通过在抽象处理者中定义明确的职责划分规则来实现这一点。
动态组装责任链:
可以考虑使用工厂或者配置文件等方式,动态地组装责任链,提高灵活性。
这样可以在不修改代码的情况下,轻松地增加或删除处理者。
合理的链路长度:
过长的责任链可能会影响性能,因此需要权衡责任链的长度。
可以考虑使用缓存或其他优化技术来提高性能。
异常处理机制:
需要有完善的异常处理机制,确保当某个处理者出现异常时,请求能被正确地传递给下一个处理者。
可以在抽象处理者中定义统一的异常处理逻辑。
日志记录:
可以在处理者中记录日志信息,以便于追踪请求的处理过程和结果。
这有助于问题的诊断和系统的维护。
性能监控:
需要对责任链的性能进行监控,及时发现性能瓶颈,并采取相应的优化措施。
Web 服务器日志处理
每个处理者负责处理不同类型的日志,如访问日志、错误日志、安全日志等。
使用责任链模式可以灵活地添加或删除日志处理器,而不影响整体系统。
银行交易审批流程:
不同级别的员工负责审批不同金额的交易请求。
使用责任链模式可以方便地调整审批流程,增加或删除审批节点。
异常处理管理:
系统中出现各种异常,需要由不同的处理器进行处理。
使用责任链模式可以灵活地增加或修改异常处理逻辑,提高系统的可扩展性。
责任链模式体现在明确职责划分、动态组装责任链、合理的链路长度、异常处理机制、日志记录和性能监控等方面,可以广泛应用于各种需要灵活处理请求的场景中。
6.总结
总之,责任链模式通过创建一条处理者链,实现了请求发送者与请求处理者解耦,提高了系统的灵活性和可扩展性。