别称: 职责链模式,命令链,CoR, Chain Of Command, Chain of Responsibility
作用: 责任链模式属于行为设计模式中的一种,其作用是将收到的请求沿着处理链进行调用处理,链上的每一处理者都可以对请求进行操作处理,或者传递给下一个处理者。比如:
场景 假设你正在开发一个商城系统(好像举例就容易举到商城上去,谁能告诉我为什么!!!),user对于订单的操作只需要登录认证即可。但是除此之外,管理者也有对全部订单的处理权限。
那么一个最基本的版本的处理模型就如下:
但是随着你的商城慢慢被越来越多的人使用,由于过于简单的访问检查设计,暴露出来的问题也越来越多,需要添加的检查步骤也会逐渐变多:同一请求的接口幂等设计问题(一般返回缓存中的结果即可),请求数据的真实性检查,用户白名单黑名单等等。那么,这中间的检查步骤会渐渐的变得复杂起来,检查部分的代码也会变得越来越多,可维护性与可读性也变得越来越低。
此时,就该我们的责任链模式闪亮登场了:
解决方案: 我们可以将每一个检查步骤封装为一个类,所有的这些类组合起来形成一个链。链上的每一个处理者对象都应该有一个对下一个处理对象的引用。每一个处理者对象都应该可以对请求进行检查,同时决定是直接跳出处理(检查失败) 还是交给下一个处理者继续检查。所有的处理者只关心自己的检查逻辑,而不关心其他检查者的检查内容。
代码实现
# 责任链模式
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any, Optional
class BaseHandler(ABC):
@abstractmethod
def set_next_handler(self, handler: BaseHandler) -> BaseHandler:
pass
@abstractmethod
def handle(self, request: Any) -> Optional[str]:
pass
class Handler(BaseHandler):
def __init__(self):
self.next_handler = None
def set_next_handler(self, handler: BaseHandler) -> BaseHandler:
self.next_handler = handler
return handler
@abstractmethod
def handle(self, request: Any) -> str:
if self.next_handler:
return self.next_handler.handle(request)
return None
class LoginHandler(Handler):
def handle(self, request: map)->str:
if request["Login"]:
return super().handle(request)
return "the request are not login"
class AccessHandler(Handler):
def handle(self, request: map) -> str:
if request["Access"]:
return super().handle(request)
return "the request can not access the order"
class DataHandler(Handler):
def handle(self, request: map) -> str:
if request["Data"]:
return super().handle(request)
return "the request data are not origin"
def TestChain(handler: BaseHandler) -> None:
request1 = {
"Login" : True,
"Access" : True,
"Data" : True,
}
request2 = {
"Login" : False,
"Access" : True,
"Data" : True,
}
request3 = {
"Login" : True,
"Access" : False,
"Data" : True,
}
request4 = {
"Login" : True,
"Access" : True,
"Data" : False,
}
requests = [request1, request2, request3, request4]
for request in requests:
result = handler.handle(request)
if result:
print(result)
else:
print("Access Ok")
if __name__ == "__main__":
loginHandler = LoginHandler()
dataHandler = DataHandler()
accessHandler = AccessHandler()
dataHandler.set_next_handler(loginHandler).set_next_handler(accessHandler)
print("origin chain: login -> access")
TestChain(loginHandler)
print("\n\nnew chain: data -> login -> access")
TestChain(dataHandler)
运行结果如下:
origin chain: login -> access
Access Ok
the request are not login
the request can not access the order
Access Ok
new chain: data -> login -> access
Access Ok
the request are not login
the request can not access the order
the request data are not origin
c++代码版见githubc++