• 设计模式——22. 责任链模式


    1. 说明

    责任链模式是一种行为设计模式,它允许你创建一个对象链,每个对象都包含了请求的一部分处理逻辑,并且请求按照链的顺序依次传递,直到有一个对象处理它为止。责任链模式通常用于将一个请求从发送者传递给多个接收者,直到有一个接收者处理请求为止。
    责任链模式的核心概念包括以下要点:

    1. 处理者对象链: 责任链由多个处理者(处理对象)组成,每个处理者都知道下一个处理者。请求从链的起点进入,然后依次沿着链传递,直到某个处理者能够处理请求。
    2. 请求处理: 每个处理者都有一个处理请求的方法,当它无法处理请求时,会将请求传递给链中的下一个处理者。处理者可以决定是否处理请求,也可以将请求传递给下一个处理者。
    3. 动态性: 责任链模式允许你在运行时动态添加或删除处理者,因此可以灵活地调整处理逻辑。
    4. 避免显式引用: 请求发送者不需要知道链中的哪个处理者将处理请求,它只需要将请求发送到链的起点。

    责任链模式通常用于以下情况:

    • 当有多个对象可以处理请求,但请求的处理者在运行时确定。
    • 当请求的发送者和接收者之间需要解耦,以便更容易地添加或修改处理者。
    • 当需要按照一定顺序处理请求。

    一个常见的例子是审批流程,其中不同级别的审批者依次审批请求,直到最终决策被达成。责任链模式可以有效地支持这种工作流程

    2. 使用的场景

    责任链模式通常用于以下情况和场景:
    3. 请求的处理者不确定: 当请求的处理者在运行时才能确定,并且需要动态配置或修改处理逻辑时,责任链模式非常有用。这使得可以轻松地添加、移除或重新排序处理者,而无需更改请求的发送者。
    4. 避免发送者和接收者之间的直接耦合: 使用责任链模式,请求的发送者不需要知道具体哪个对象将处理请求,只需要将请求发送到链的起点。这可以降低系统中不同组件之间的耦合度。
    5. 按顺序处理请求: 当请求需要按照一定顺序依次处理时,责任链模式非常适合。例如,审批流程中,不同级别的审批者依次处理请求。
    6. 处理多个请求对象: 当系统中有多个请求对象,而每个请求可能需要被不同的处理者处理时,责任链模式可以有效地管理和处理这些请求。
    7. 解耦复杂的处理逻辑: 当处理逻辑复杂且难以单独管理时,可以将处理逻辑分解成多个处理者,每个处理者负责处理一部分逻辑,从而简化系统的设计和维护。
    8. 错误处理和日志记录: 在错误处理和日志记录方面,责任链模式可以用于捕获异常、记录日志或执行特定的错误处理逻辑。
    9. 权限验证: 在应用程序中,可以使用责任链模式来处理用户权限验证。不同的处理者可以检查用户是否具有执行某个操作的权限。

    总之,责任链模式在需要将请求从发送者传递给多个接收者,并且能够在运行时动态配置处理逻辑的情况下非常有用。这种模式提供了一种可扩展和灵活的方法来管理复杂的请求处理流程。

    3. 应用例子

    以下是一个使用 Python 实现的简单责任链模式示例,模拟请求处理链,请求从一个处理者传递到另一个处理者,直到有一个处理它为止。这个示例将处理请求的问题按照不同的难度级别分配给不同的处理者。

    # 抽象处理者类
    class Handler:
        def __init__(self, successor=None):
            self.successor = successor
    
        def handle_request(self, request):
            if self.successor:
                self.successor.handle_request(request)
    
    # 具体处理者类
    class EasyHandler(Handler):
        def handle_request(self, request):
            if request <= 10:
                print(f"EasyHandler: Handling request {request}")
            else:
                super().handle_request(request)
    
    class MediumHandler(Handler):
        def handle_request(self, request):
            if 10 < request <= 50:
                print(f"MediumHandler: Handling request {request}")
            else:
                super().handle_request(request)
    
    class HardHandler(Handler):
        def handle_request(self, request):
            if request > 50:
                print(f"HardHandler: Handling request {request}")
    
    # 客户端代码
    if __name__ == "__main__":
        # 创建处理者链
        hard_handler = HardHandler()
        medium_handler = MediumHandler(hard_handler)
        easy_handler = EasyHandler(medium_handler)
    
        # 发送不同难度级别的请求
        requests = [5, 15, 60]
        for request in requests:
            easy_handler.handle_request(request)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    4. 实现要素

    责任链模式的实现要素包括以下关键角色:

    1. 抽象处理者(Handler):定义处理请求的接口或抽象类。通常包含一个指向下一个处理者的引用(后继者),并且提供一个处理请求的方法(handleRequest)。这个角色可以是抽象类或接口。
    2. 具体处理者(ConcreteHandler):实现抽象处理者接口,负责处理具体的请求。如果自己无法处理请求,可以将请求传递给下一个处理者。每个具体处理者通常只能处理一类请求。
    3. 客户端(Client):创建请求并将其发送到处理者链的起点。客户端通常不需要知道链中的具体处理者,只需要将请求发送给第一个处理者。

    5. Java/golang/javascrip/C++ 等语言实现方式

    5.1 Java实现

    上述例子用Java语言实现示例如下:

    // 抽象处理者接口
    interface Handler {
        void handleRequest(int request);
        void setSuccessor(Handler successor);
    }
    
    // 具体处理者类
    class EasyHandler implements Handler {
        private Handler successor;
    
        @Override
        public void handleRequest(int request) {
            if (request <= 10) {
                System.out.println("EasyHandler: Handling request " + request);
            } else if (successor != null) {
                successor.handleRequest(request);
            }
        }
    
        @Override
        public void setSuccessor(Handler successor) {
            this.successor = successor;
        }
    }
    
    class MediumHandler implements Handler {
        private Handler successor;
    
        @Override
        public void handleRequest(int request) {
            if (request > 10 && request <= 50) {
                System.out.println("MediumHandler: Handling request " + request);
            } else if (successor != null) {
                successor.handleRequest(request);
            }
        }
    
        @Override
        public void setSuccessor(Handler successor) {
            this.successor = successor;
        }
    }
    
    class HardHandler implements Handler {
        @Override
        public void handleRequest(int request) {
            if (request > 50) {
                System.out.println("HardHandler: Handling request " + request);
            }
        }
    
        @Override
        public void setSuccessor(Handler successor) {
            // 最后一个处理者,不设置后继者
        }
    }
    
    // 客户端代码
    public class Main {
        public static void main(String[] args) {
            // 创建处理者链
            Handler hardHandler = new HardHandler();
            Handler mediumHandler = new MediumHandler();
            Handler easyHandler = new EasyHandler();
    
            // 设置处理者的后继者
            easyHandler.setSuccessor(mediumHandler);
            mediumHandler.setSuccessor(hardHandler);
    
            // 发送不同难度级别的请求
            int[] requests = {5, 15, 60};
            for (int request : requests) {
                easyHandler.handleRequest(request);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    在这个 Java 示例中,我们定义了一个 Handler 接口和三个具体的处理者类,然后在客户端代码中创建了处理者链,按顺序将请求发送给链的起点 easyHandler。不同难度级别的请求将由不同的处理者处理,或者传递给下一个处理者。

    5.2 Golang实现

    上述例子用golang实现示例如下:

    package main
    
    import (
            "fmt"
    )
    
    // Handler 接口定义了处理请求的方法和设置后继者的方法
    type Handler interface {
            HandleRequest(request int)
            SetSuccessor(successor Handler)
    }
    
    // EasyHandler 是具体处理者,处理难度级别低的请求
    type EasyHandler struct {
            successor Handler
    }
    
    func (e *EasyHandler) HandleRequest(request int) {
            if request <= 10 {
                    fmt.Printf("EasyHandler: Handling request %d\n", request)
            } else if e.successor != nil {
                    e.successor.HandleRequest(request)
            }
    }
    
    func (e *EasyHandler) SetSuccessor(successor Handler) {
            e.successor = successor
    }
    
    // MediumHandler 是具体处理者,处理难度级别中等的请求
    type MediumHandler struct {
            successor Handler
    }
    
    func (m *MediumHandler) HandleRequest(request int) {
            if request > 10 && request <= 50 {
                    fmt.Printf("MediumHandler: Handling request %d\n", request)
            } else if m.successor != nil {
                    m.successor.HandleRequest(request)
            }
    }
    
    func (m *MediumHandler) SetSuccessor(successor Handler) {
            m.successor = successor
    }
    
    // HardHandler 是具体处理者,处理难度级别高的请求
    type HardHandler struct{}
    
    func (h *HardHandler) HandleRequest(request int) {
            if request > 50 {
                    fmt.Printf("HardHandler: Handling request %d\n", request)
            }
    }
    
    func (h *HardHandler) SetSuccessor(successor Handler) {
            // 最后一个处理者,不设置后继者
    }
    
    func main() {
            // 创建处理者链
            hardHandler := &HardHandler{}
            mediumHandler := &MediumHandler{}
            easyHandler := &EasyHandler{}
    
            // 设置处理者的后继者
            easyHandler.SetSuccessor(mediumHandler)
            mediumHandler.SetSuccessor(hardHandler)
    
            // 发送不同难度级别的请求
            requests := []int{5, 15, 60}
            for _, request := range requests {
                    easyHandler.HandleRequest(request)
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    在这个 Go 示例中,我们定义了一个 Handler 接口和三个具体的处理者类型。然后,我们创建了处理者链,并设置了处理者的后继者。不同难度级别的请求将由不同的处理者处理,或者传递给下一个处理者。

    5.3 Javascript实现

    上述例子用javascript实现示例如下:

    // 抽象处理者类
    class Handler {
        constructor() {
            this.successor = null;
        }
    
        setSuccessor(successor) {
            this.successor = successor;
        }
    
        handleRequest(request) {
            if (this.successor) {
                this.successor.handleRequest(request);
            }
        }
    }
    
    // 具体处理者类
    class EasyHandler extends Handler {
        handleRequest(request) {
            if (request <= 10) {
                console.log(`EasyHandler: Handling request ${request}`);
            } else {
                super.handleRequest(request);
            }
        }
    }
    
    class MediumHandler extends Handler {
        handleRequest(request) {
            if (request > 10 && request <= 50) {
                console.log(`MediumHandler: Handling request ${request}`);
            } else {
                super.handleRequest(request);
            }
        }
    }
    
    class HardHandler extends Handler {
        handleRequest(request) {
            if (request > 50) {
                console.log(`HardHandler: Handling request ${request}`);
            }
        }
    }
    
    // 客户端代码
    const hardHandler = new HardHandler();
    const mediumHandler = new MediumHandler();
    const easyHandler = new EasyHandler();
    
    easyHandler.setSuccessor(mediumHandler);
    mediumHandler.setSuccessor(hardHandler);
    
    const requests = [5, 15, 60];
    for (const request of requests) {
        easyHandler.handleRequest(request);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在这个 JavaScript 示例中,我们定义了一个 Handler 类作为抽象处理者,并创建了三个具体处理者类 EasyHandler、MediumHandler 和 HardHandler。然后,我们设置了处理者的后继者,并发送不同难度级别的请求。根据请求的难度级别,不同的处理者将负责处理请求或将其传递给下一个处理者。

    5.4 C++实现

    上述例子用C++实现如下:

    #include 
    
    // 抽象处理者类
    class Handler {
    public:
        virtual void handleRequest(int request) {
            if (successor) {
                successor->handleRequest(request);
            }
        }
    
        void setSuccessor(Handler* successor) {
            this->successor = successor;
        }
    
    private:
        Handler* successor = nullptr;
    };
    
    // 具体处理者类
    class EasyHandler : public Handler {
    public:
        void handleRequest(int request) override {
            if (request <= 10) {
                std::cout << "EasyHandler: Handling request " << request << std::endl;
            } else {
                Handler::handleRequest(request);
            }
        }
    };
    
    class MediumHandler : public Handler {
    public:
        void handleRequest(int request) override {
            if (request > 10 && request <= 50) {
                std::cout << "MediumHandler: Handling request " << request << std::endl;
            } else {
                Handler::handleRequest(request);
            }
        }
    };
    
    class HardHandler : public Handler {
    public:
        void handleRequest(int request) override {
            if (request > 50) {
                std::cout << "HardHandler: Handling request " << request << std::endl;
            }
        }
    };
    
    int main() {
        // 创建处理者链
        HardHandler hardHandler;
        MediumHandler mediumHandler;
        EasyHandler easyHandler;
    
        // 设置处理者的后继者
        easyHandler.setSuccessor(&mediumHandler);
        mediumHandler.setSuccessor(&hardHandler);
    
        // 发送不同难度级别的请求
        int requests[] = {5, 15, 60};
        for (int request : requests) {
            easyHandler.handleRequest(request);
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    在这个 C++ 示例中,我们定义了一个 Handler 类作为抽象处理者,并创建了三个具体处理者类 EasyHandler、MediumHandler 和 HardHandler。然后,我们设置了处理者的后继者,并发送不同难度级别的请求。根据请求的难度级别,不同的处理者将负责处理请求或将其传递给下一个处理者。

    6. 练习题

    当用户注册一个账户时,通常需要进行一系列验证,如用户名是否重复、密码是否符合规范、邮箱是否有效等。使用责任链模式来处理这些验证可以让代码更灵活和可扩展。

    要求
    使用责任链模式实现以下验证步骤:

    1. 用户名是否重复验证:检查用户名是否已经存在于数据库中,如果存在则验证失败,否则继续下一步。
    2. 密码复杂度验证:检查密码是否符合一定的复杂度规范,如包含至少一个大写字母、一个小写字母和一个数字,否则验证失败,否则继续下一步。
    3. 邮箱有效性验证:检查邮箱地址是否有效,如果无效则验证失败,否则验证成功。
      使用责任链模式创建一个验证链,将验证步骤串联起来。如果某个验证步骤失败,验证就会停止并返回失败结果;如果所有验证步骤都通过,验证将返回成功结果。

    你可以使用 C++、Java、Python 或任何其他编程语言来实现这个练习。
    你可以在评论区里或者私信我回复您的答案,这样我或者大家都能帮你解答,期待着你的回复~

  • 相关阅读:
    今天的码农女孩学习了关于react子父组件传值的知识,并做了小练习
    Mac GPU MPS常用方法
    线扫相机DALSA--分频倍频计算公式及原理
    基于中间件的密码泛在化保障技术研究
    Leetcode - 周赛393
    (二十一)数据结构-二叉排序树、平衡二叉树、散列查找
    某些按钮,用click函数来点击无效果,这个时候用鼠标模拟点击试试!
    行业类软文有哪些?媒介盒子告诉你
    Go实现LogCollect:海量日志收集系统【下篇——开发LogTransfer】
    一文带你了解BI的前世今身与企业数字化转型的关系
  • 原文地址:https://blog.csdn.net/guohuang/article/details/133801364