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

本文介绍了责任链模式,一种行为设计模式,用于将请求从发送者传递给多个处理者,直至找到能处理的接收者。文章详细讲解了模式的工作原理、适用场景和编程语言实现示例,以及如何在用户账户注册验证中应用此模式。
摘要由CSDN通过智能技术生成

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)

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);
        }
    }
}

在这个 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)
        }
}

在这个 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);
}

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

5.4 C++实现

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

#include <iostream>

// 抽象处理者类
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;
}

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

6. 练习题

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guohuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值