一、说明
旨在将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。
(一) 解决问题
将请求的发送者和接受者解耦,并使请求随着处理对象链传递,优化系统内部处理逻辑
(二) 使用场景
- 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时
- 当必须按顺序执行多个处理者时
- 当一个对象需要在运行时动态地确定其处理对象时
二、结构
- **处理者(Handler)**声明了所有具体处理者的通用接口。该接口通常仅包含单个方法用于请求处理,但有时其还会包含一个设置链上下个处理者的方法。
- **基础处理者(BaseHandler)**是一个可选的类,你可以将所有处理者共用的样本代码放置在其中。通常情况下,该类中定义了一个保存对于下个处理者引用的成员变量。客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。该类还可以实现默认的处理行为:确定下个处理者存在后再将请求传递给它。
- **具体处理者(ConcreteHandlers)**包含处理请求的实际代码。每个处理者接收到请求后,都必须决定是否进行处理,以及是否沿着链传递请求。处理者通常是独立且不可变的,需要通过构造函数一次性地获得所有必要地数据。
- **客户端(Client)**可根据程序逻辑一次性或者动态地生成链。值得注意的是,请求可发送给链上的任意一个处理者,而非必须是第一个处理者。
三、伪代码
python
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
责任链模式
例:一个产品生产流水线,需要三个环节:生产、质检、包装。每个环节只能由对应的工人处理,如果无法处理则传递给下一个环节处理。
"""
from abc import ABC, abstractmethod
class Worker(ABC):
"""抽象处理类"""
@abstractmethod
def handle_product(self, product):
pass
@abstractmethod
def set_next_worker(self, worker):
pass
class Producer(Worker):
"""具体处理类"""
def __init__(self):
self.next_worker = None
def set_next_worker(self, worker):
self.next_worker = worker
def handle_product(self, product):
if product.get("process") == "produce":
print("生产商正在生产产品")
elif self.next_worker:
self.next_worker.handle_product(product)
class Inspector(Worker):
"""具体处理类"""
def __init__(self):
self.next_worker = None
def set_next_worker(self, worker):
self.next_worker = worker
def handle_product(self, product):
if product.get("process") == "inspect":
print("检验员正在检验产品")
elif self.next_worker:
self.next_worker.handle_product(product)
class Packer(Worker):
"""具体处理类"""
def __init__(self):
self.next_worker = None
def set_next_worker(self, worker):
self.next_worker = worker
def handle_product(self, product):
if product.get("process") == "pack":
print("包装商正在包装产品")
elif self.next_worker:
self.next_worker.handle_product(product)
if __name__ == "__main__":
"""
生产商正在生产产品
检验员正在检验产品
包装商正在包装产品
"""
producer = Producer()
inspector = Inspector()
packer = Packer()
producer.set_next_worker(inspector)
inspector.set_next_worker(packer)
product1 = {"process": "produce"}
product2 = {"process": "inspect"}
product3 = {"process": "pack"}
producer.handle_product(product1)
producer.handle_product(product2)
producer.handle_product(product3)
四、优缺点
优点
- **降低耦合度:**将请求的发送者和接收者解耦,每个处理对象只需关注自己的处理逻辑,不需要知道整个处理链的结构,降低了对象之间的耦合度。
- **灵活性:**允许动态地添加、移除或修改处理对象,可以根据需要调整处理链的结构,提高了系统的灵活性。
- **简化对象之间的交互:**将处理对象的关系组织成一条链,简化了对象之间的交互,使得系统更易于理解和维护。
- **可扩展性:**允许动态地添加新的处理对象,因此可以很容易地扩展系统的功能,满足不断变化的需求。
缺点
- **性能问题:**责任链模式可能会导致请求在整个处理链上传递,直到有一个处理对象处理请求为止,如果处理链过长或者处理对象之间的处理时间不均匀,可能会影响系统的性能。
- **调试困难:**责任链模式将请求的处理分散在多个处理对象中,可能会导致调试时比较困难,特别是处理链比较长的情况下。