定义
- 为避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求。将这些接收对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
职责模式的设计思想
代码框架
from abc import ABCMeta, abstractmethod
# 引入ABCMeta和abstractmethod来定义抽象类和抽象方法
class Request:
"""请求(内容)"""
def __init__(self, name, dayoff, reason):
self.__name = name
self.__dayoff = dayoff
self.__reason = reason
self.__leader = None
def getName(self):
return self.__name
def getDayOff(self):
return self.__dayoff
def getReason(self):
return self.__reason
class Responsible(metaclass=ABCMeta):
"""责任人抽象类"""
def __init__(self, name, title):
self.__name = name
self.__title = title
self._nextHandler = None
def getName(self):
return self.__name
def getTitle(self):
return self.__title
def setNextHandler(self, nextHandler):
self._nextHandler = nextHandler
def getNextHandler(self):
return self._nextHandler
def handleRequest(self, request):
"""请求处理"""
# 当前责任人处理请求
self._handleRequestImpl(request)
# 如果存在下一个责任人,则将请求传递(提交)给下一个责任人
if (self._nextHandler is not None):
self._nextHandler.handleRequest(request)
@abstractmethod
def _handleRequestImpl(self, request):
"""真正处理请求的方法"""
pass
类图
基于框架的实现
from abc import ABCMeta, abstractmethod
# 引入ABCMeta和abstractmethod来定义抽象类和抽象方法
class Request:
"""请求(内容)"""
def __init__(self, name, dayoff, reason):
self.__name = name
self.__dayoff = dayoff
self.__reason = reason
self.__leader = None
def getName(self):
return self.__name
def getDayOff(self):
return self.__dayoff
def getReason(self):
return self.__reason
class Responsible(metaclass=ABCMeta):
"""责任人抽象类"""
def __init__(self, name, title):
self.__name = name
self.__title = title
self._nextHandler = None
def getName(self):
return self.__name
def getTitle(self):
return self.__title
def setNextHandler(self, nextHandler):
self._nextHandler = nextHandler
def getNextHandler(self):
return self._nextHandler
def handleRequest(self, request):
"""请求处理"""
# 当前责任人处理请求
self._handleRequestImpl(request)
# 如果存在下一个责任人,则将请求传递(提交)给下一个责任人
if (self._nextHandler is not None):
self._nextHandler.handleRequest(request)
@abstractmethod
def _handleRequestImpl(self, request):
"""真正处理请求的方法"""
pass
class Person:
"""请求者(请假人)"""
def __init__(self, name):
self.__name = name
self.__leader = None
def setName(self, name):
self.__name = name
def getName(self):
return self.__name
def setLeader(self, leader):
self.__leader = leader
def getLeader(self):
return self.__leader
def sendReuqest(self, request):
print("%s 申请请假 %d 天。请假事由:%s" % (self.__name, request.getDayOff(), request.getReason()))
if (self.__leader is not None):
self.__leader.handleRequest(request)
class Supervisor(Responsible):
"""主管"""
def __init__(self, name, title):
super().__init__(name, title)
def _handleRequestImpl(self, request):
if (request.getDayOff() <= 2):
print("同意 %s 请假,签字人:%s(%s)" % (request.getName(), self.getName(), self.getTitle()))
class DepartmentManager(Responsible):
"""部门总监"""
def __init__(self, name, title):
super().__init__(name, title)
def _handleRequestImpl(self, request):
if (request.getDayOff() > 2 and request.getDayOff() <= 5):
print("同意 %s 请假,签字人:%s(%s)" % (request.getName(), self.getName(), self.getTitle()))
class CEO(Responsible):
"""CEO"""
def __init__(self, name, title):
super().__init__(name, title)
def _handleRequestImpl(self, request):
if (request.getDayOff() > 5 and request.getDayOff() <= 22):
print("同意 %s 请假,签字人:%s(%s)" % (request.getName(), self.getName(), self.getTitle()))
class Administrator(Responsible):
"""行政人员"""
def __init__(self, name, title):
super().__init__(name, title)
def _handleRequestImpl(self, request):
print("%s 的请假申请已审核,情况属实!已备案处理。处理人:%s(%s)\n" % (request.getName(), self.getName(), self.getTitle()))
def testChainOfResponsibility():
directLeader = Supervisor("Eren", "客户端研发部经理")
departmentLeader = DepartmentManager("Eric", "技术研发中心总监")
ceo = CEO("Helen", "创新文化公司CEO")
administrator = Administrator("Nina", "行政中心总监")
directLeader.setNextHandler(departmentLeader)
departmentLeader.setNextHandler(ceo)
ceo.setNextHandler(administrator)
sunny = Person("Sunny")
sunny.setLeader(directLeader)
sunny.sendReuqest(Request(sunny.getName(), 1, "参加MDCC大会。"))
tony = Person("Tony")
tony.setLeader(directLeader)
tony.sendReuqest(Request(tony.getName(), 5, "家里有紧急事情!"))
pony = Person("Pony")
pony.setLeader(directLeader)
pony.sendReuqest(Request(pony.getName(), 15, "出国深造。"))
# testAskForLeave()
testChainOfResponsibility()
模型说明
- 设计要点
- 请求者与请求内容:确认谁要发送请求,发送请求的对象称为请求者。请求的内容通过发送请求时的参数进行传递。
- 有哪些责任人:责任人是构成责任链的关键要素。请求的流动方向是链条中的线,而责任人则是链条上的节点,线和节点共同构成了一条链条。
- 对责任人进行抽象:真实世界中的责任人多种多样,纷繁复杂,有不同的职责和功能;但他们也有一个共同的特征—都可以处理请求。所以需要对责任人进行抽象,使他们具有责任的可传递性。
- 责任人可自由组合:责任链上的责任人可以根据业务的具体逻辑进行自由的组合和排序。
- 优缺点
- 优点:
- 降低耦合度。它将请求的发送者和接收者解耦。
- 简化了对象。它使得对象不需要知道链的结构。
- 增强给对象指派职责的灵活性。可改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任人。
- 增加新的处理类很方便。
- 缺点:
- 不能保证请求一定被接收。
- 系统性能将受到一定的影响,而且在进行代码调试时不太方便,可能会造成循环调用。
应用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求在运行时刻自动确定。
- 请求的处理具有明显的一层层传递关系。
- 请求的处理流程和顺序需要程序运行时动态确定。
- 常见的审批流程(账务报销、转岗申请等)。