一、介绍
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
二、责任链模式
1、责任链的结构和应用场景
结构:
- 抽象处理者:定义了处理请求的抽象方法和一个设置责任链的下一个处理者的方法。
- 具体处理者:实现处理请求的方法,判断自己能否处理本次请求,如果能,则处理,如果不能,则把请求转发给责任链的下一个处理者。
- 客户类:创建处理链,对链头提交请求,并不需要关心处理细节。
处理原则:
- 客户类发起请求,创建一个责任链。
- 将请求发送给第一个对象,让其处理。
- 此时对象判断是否可以处理该请求。
- 若可以,则进行处理。
- 若不可以,则把请求转发给下一个对象。
- 下一个对象判断是否可以处理该请求,重复该过程(3、4、5),直到达到链尾。
使用场景:
- 若某个请求可以由多个对象进行处理,但具体由哪个对象处理该请求则是由请求内容和对象处理权限确定。
- 在请求处理者不明确的情况下,对多个处理者中的一个提交请求。
- 需要动态处理一组对象处理请求,比如新增新的处理者。
2、示例
假设现在有一个员工管理系统:
1.外出公干时间少于3天的申请,由项目经理审批即可
2.外出公干时间大于3天小于7天的申请,需要项目经理审批完之后,再由部门主管进行审批
3.外出公干时间大于7天的申请,不仅需要项目经理和部门主管进行审批,还需要总经理进行最后的审批
那么我们使用责任链模式进行处理
import abc class Manager(metaclass=abc.ABCMeta): """抽象处理者""" def __init__(self, name): self.superior = None # 责任链的下一个处理者 self.name = name def setSuperior(self, superior): # 设置责任链的下一个处理者 self.superior = superior @abc.abstractmethod def handleRequest(self, clientRequest): # 处理请求 pass class ProjectManager(Manager): """具体处理者:项目经理""" def handleRequest(self, clientRequest): if clientRequest.applicationType == "business" and clientRequest.businessDay <= 3: return "外出公干%s天,%s审批意见:OK,审批结束" % ( clientRequest.businessDay, self.name) else: print("外出公干%s天,%s审批意见:OK,审批由%s继续处理" % ( clientRequest.businessDay, self.name, self.superior.name)) return self.superior.handleRequest(clientRequest) class DepartmentHead(Manager): """具体处理者:部门主管""" def handleRequest(self, clientRequest): if clientRequest.applicationType == "business" and clientRequest.businessDay <= 7: return "外出公干%s天,%s审批意见:OK,审批结束" % ( clientRequest.businessDay, self.name) else: print("外出公干%s天,%s审批意见:OK,审批由%s继续处理" % ( clientRequest.businessDay, self.name, self.superior.name)) return self.superior.handleRequest(clientRequest) class President(Manager): """具体处理者:总经理""" def handleRequest(self, clientRequest): if clientRequest.applicationType == "business": return "%s审批意见:OK,审批结束" % self.name class Client(object): """客户类:发起请求""" def __init__(self, applicationType, businessDay): self.applicationType = applicationType self.businessDay = businessDay def submit(self, manager): response = manager.handleRequest(self) print(response) return response if __name__ == '__main__': # 初始化责任链 project_manager = ProjectManager('项目经理') department_head = DepartmentHead('部门主管') president = President('总经理') project_manager.setSuperior(department_head) # 项目经理的上级是部门主管 department_head.setSuperior(president) # 部门主管的上级是总经理 # 客户类进行请求 client = Client(applicationType="business", businessDay=2) client.submit(project_manager) print("-------------------------- request 1 end --------------------------") client = Client(applicationType="business", businessDay=6) client.submit(project_manager) print("-------------------------- request 2 end --------------------------") client = Client(applicationType="business", businessDay=14) client.submit(project_manager) print("-------------------------- request 3 end --------------------------")
结果: