责任链模式
定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
场景
预先不知道由哪个对象来处理某种特定请求时。
让多个对象处理一个请求时。
例如
公司请假系统,员工请假3天以内(包括3天),只要直属经理批准即可;
如果请假3-7天,不仅要直属经理批准,还要部门经理最终批准;
如果请假大于7天,不仅要前两个经理批准,还要总经理最终批准。
实现
用责任链实现上面的公司请假系统
class Manager:
superior = None
name = ''
def __init__(self, name):
self.name = name
def set_superior(self, superior):
self.superior = superior
def handle_request(self, request):
pass
class LineManager(Manager):
def handle_request(self, request):
if request.requestType == '请假' and request.number <= 3:
print(f'申请内容:{request.requestContent} 实际天数:{request.number} {self.name}:批准,结束')
else:
print(f'申请内容:{request.requestContent} 实际天数:{request.number} {self.name}:同意,进入下一环节')
if self.superior is not None:
self.superior.handle_request(request)
class DepartmentManager(Manager):
def handle_request(self, request):
if request.requestType == '请假' and request.number <= 7:
print(f'申请内容:{request.requestContent} 实际天数:{request.number} {self.name}:批准,结束')
else:
print(f'申请内容:{request.requestContent} 实际天数:{request.number} {self.name}:同意,进入下一环节')
if self.superior is not None:
self.superior.handle_request(request)
class GeneralManager(Manager):
def handle_request(self, request):
if request.requestType == '请假':
print(f'申请内容:{request.requestContent} 实际天数:{request.number} {self.name}:批准,结束')
class Request:
requestType = ''
requestContent = ''
number = 0
if __name__ == "__main__":
line_manager = LineManager('直属经理')
department_manager = DepartmentManager('部门经理')
general_manager = GeneralManager('总经理')
line_manager.set_superior(department_manager) # 设置上司,组装链式结构
department_manager.set_superior(general_manager) # 设置上司,组装链式结构
req = Request()
req.requestType = '请假'
req.requestContent = '请假1天'
req.number = 1
line_manager.handle_request(req)
req.requestType = '请假'
req.requestContent = '请假5天'
req.number = 5
line_manager.handle_request(req)
req.requestType = '请假'
req.requestContent = '请假10天'
req.number = 10
line_manager.handle_request(req)
实现过程
1.组装一个对象链(链表、树或者其他便捷的数据结构)。
2.一开始将请求发送给第一个对象,让其处理。
3.对象决定是否处理该请求。
4.对象将请求转发给下一个对象。
5.重复该过程,直到达到链尾。
优点
将请求者与处理者分离,请求者并不知道请求是被哪个处理者所处理,易于扩展。
缺点
1.如果责任链比较长,会有比较大的性能问题;
2.如果责任链比较长,若业务出现问题,比较难定位是哪个处理者的问题。