设计模式: 责任链模式

357 阅读3分钟

别称: 职责链模式,命令链,CoR, Chain Of Command, Chain of Responsibility

作用: 责任链模式属于行为设计模式中的一种,其作用是将收到的请求沿着处理链进行调用处理,链上的每一处理者都可以对请求进行操作处理,或者传递给下一个处理者。比如:

image.png

场景 假设你正在开发一个商城系统(好像举例就容易举到商城上去,谁能告诉我为什么!!!),user对于订单的操作只需要登录认证即可。但是除此之外,管理者也有对全部订单的处理权限。

那么一个最基本的版本的处理模型就如下:

image.png

但是随着你的商城慢慢被越来越多的人使用,由于过于简单的访问检查设计,暴露出来的问题也越来越多,需要添加的检查步骤也会逐渐变多:同一请求的接口幂等设计问题(一般返回缓存中的结果即可),请求数据的真实性检查,用户白名单黑名单等等。那么,这中间的检查步骤会渐渐的变得复杂起来,检查部分的代码也会变得越来越多,可维护性与可读性也变得越来越低。

此时,就该我们的责任链模式闪亮登场了:

解决方案: 我们可以将每一个检查步骤封装为一个类,所有的这些类组合起来形成一个链。链上的每一个处理者对象都应该有一个对下一个处理对象的引用。每一个处理者对象都应该可以对请求进行检查,同时决定是直接跳出处理(检查失败) 还是交给下一个处理者继续检查。所有的处理者只关心自己的检查逻辑,而不关心其他检查者的检查内容。

代码实现

# 责任链模式
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++