程序员必知!责任链模式的实战应用与案例分析

程序员必知!责任链模式的实战应用与案例分析 - 程序员古德

责任链模式让多个对象依次处理请求,降低发送者和接收者的耦合度,以在线购物为例,用户提交订单需经多步验证,通过责任链模式,验证器按顺序处理请求,先用户身份,再支付方式,最后配送地址,任一验证失败即停止流程并反馈错误,责任链模式提升了代码的灵活性和可扩展性。

定义

程序员必知!责任链模式的实战应用与案例分析 - 程序员古德

责任链模式是一种行为设计模式,它使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,这些对象形成一个处理请求的链,client只需要将请求发送到链头即可。举一个业务中的例子:假设有一个在线购物网站,用户可以在网站上浏览商品并购买,在用户提交订单时,需要验证用户的身份、支付方式、配送地址等信息,可以使用责任链模式来处理这个流程,假设有以下验证器:

  1. 用户身份验证器:验证用户的身份信息是否正确。
  2. 支付方式验证器:验证用户的支付方式是否可用。
  3. 配送地址验证器:验证用户的配送地址是否有效。

可以将这些验证器组成一个责任链,并让它们依次处理请求,当用户提交订单时,责任链模式的第一个验证器(用户身份验证器)会首先处理请求,如果身份信息验证通过,它会将请求传递给下一个验证器(支付方式验证器),如果支付方式验证通过,再传递给下一个验证器(配送地址验证器),如果任何一个验证器不通过,整个流程就会停止,并返回相应的错误信息给用户。这样,就可以避免将请求发送者和接收者之间的耦合关系,使得代码更加灵活和可扩展。

代码案例

程序员必知!责任链模式的实战应用与案例分析 - 程序员古德

在未使用责任链模式的情况下,可能会将多个处理逻辑放在一个方法中,或者在一个方法中依次调用多个处理方法,这种方式会导致代码的可维护性和可扩展性降低,因为当需要添加或修改处理逻辑时,必须修改这个方法,下面是一个未使用责任链模式的反例代码:

// 订单验证类,未使用责任链模式  
public class OrderValidator {  
  
    // 验证用户身份  
    private boolean validateUser(User user) {  
        // 模拟验证逻辑  
        return user != null && user.isAuthenticated();  
    }  
  
    // 验证支付方式  
    private boolean validatePayment(Payment payment) {  
        // 模拟验证逻辑  
        return payment != null && payment.isAvailable();  
    }  
  
    // 验证配送地址  
    private boolean validateAddress(Address address) {  
        // 模拟验证逻辑  
        return address != null && address.isValid();  
    }  
  
    // 提交订单方法,包含所有验证逻辑  
    public String submitOrder(User user, Payment payment, Address address) {  
        if (!validateUser(user)) {  
            return "用户身份验证失败!";  
        }  
        if (!validatePayment(payment)) {  
            return "支付方式验证失败!";  
        }  
        if (!validateAddress(address)) {  
            return "配送地址验证失败!";  
        }  
        // 所有验证通过,处理订单  
        return "订单提交成功!";  
    }  
}  
  
// 客户端调用案例  
public class Client {  
    public static void main(String[] args) {  
        OrderValidator validator = new OrderValidator();  
          
        // 创建用户、支付方式和配送地址对象  
        User user = new User(); // 假设已经认证  
        Payment payment = new Payment(); // 假设可用  
        Address address = new Address(); // 假设有效  
  
        // 提交订单并打印结果  
        String result = validator.submitOrder(user, payment, address);  
        System.out.println(result); // 输出:订单提交成功!  
  
        // 尝试使用无效的用户提交订单  
        User invalidUser = null; // 无效用户  
        String invalidUserResult = validator.submitOrder(invalidUser, payment, address);  
        System.out.println(invalidUserResult); // 输出:用户身份验证失败!  
    }  
}  
  
// 假设存在的其他类  
class User {  
    public boolean isAuthenticated() {  
        // 模拟认证逻辑  
        return true;  
    }  
}  
  
class Payment {  
    public boolean isAvailable() {  
        // 模拟支付方式可用逻辑  
        return true;  
    }  
}  
  
class Address {  
    public boolean isValid() {  
        // 模拟地址验证逻辑  
        return true;  
    }  
}

在上面的代码中,OrderValidator 类负责处理订单提交前的所有验证逻辑,submitOrder 方法中依次调用了用户验证、支付方式验证和配送地址验证方法,如果任何一个验证失败,方法都会立即返回错误信息,只有当所有验证都通过时,才会返回成功信息。

client代码创建了一个订单验证器实例,并尝试使用不同的用户提交订单,第一次提交使用有效用户,因此成功,第二次提交使用无效用户(null),因此失败,并返回相应的错误信息。

这种方式的问题是,如果需要添加新的验证逻辑(比如库存验证),必须修改 submitOrder 方法,这违反了开闭原则(对扩展开放,对修改关闭),此外,如果验证逻辑变得复杂,submitOrder 方法会变得非常庞大和难以维护。

当使用责任链模式时,可以创建一个处理请求的链,每个链上的节点都有机会处理该请求,如果某个节点能够处理请求,则处理它并可能结束链的进一步处理,否则,它将请求传递给链上的下一个节点,以下是一个使用了责任链模式的正例代码实现:

// 抽象处理者角色  
abstract class Handler {  
    protected Handler successor; // 下一个处理者  
  
    public void setSuccessor(Handler successor) {  
        this.successor = successor;  
    }  
  
    public abstract void handleRequest(Request request); // 处理请求的抽象方法  
}  
  
// 具体处理者角色A - 用户验证  
class UserHandler extends Handler {  
    @Override  
    public void handleRequest(Request request) {  
        if (request instanceof UserRequest) {  
            UserRequest userRequest = (UserRequest) request;  
            if (userRequest.getUser() != null && userRequest.getUser().isAuthenticated()) {  
                System.out.println("用户验证通过!");  
            } else {  
                System.out.println("用户验证失败!");  
                return; // 验证失败,不再传递请求  
            }  
        }  
        // 如果本处理者处理后请求未被结束,则继续传递  
        if (successor != null) {  
            successor.handleRequest(request);  
        }  
    }  
}  
  
// 具体处理者角色B - 支付验证  
class PaymentHandler extends Handler {  
    @Override  
    public void handleRequest(Request request) {  
        if (request instanceof PaymentRequest) {  
            PaymentRequest paymentRequest = (PaymentRequest) request;  
            if (paymentRequest.getPayment() != null && paymentRequest.getPayment().isAvailable()) {  
                System.out.println("支付验证通过!");  
            } else {  
                System.out.println("支付验证失败!");  
                return; // 验证失败,不再传递请求  
            }  
        }  
        // 如果本处理者处理后请求未被结束,则继续传递  
        if (successor != null) {  
            successor.handleRequest(request);  
        }  
    }  
}  
  
// 具体处理者角色C - 地址验证  
class AddressHandler extends Handler {  
    @Override  
    public void handleRequest(Request request) {  
        if (request instanceof AddressRequest) {  
            AddressRequest addressRequest = (AddressRequest) request;  
            if (addressRequest.getAddress() != null && addressRequest.getAddress().isValid()) {  
                System.out.println("地址验证通过!");  
            } else {  
                System.out.println("地址验证失败!");  
                return; // 验证失败,不再传递请求  
            }  
        }  
        // 正常情况下,这里可以处理请求或结束处理,但为了示例简单性,不在这里做任何额外处理  
    }  
}  
  
// 请求接口  
interface Request {  
}  
  
// 用户请求  
class UserRequest implements Request {  
    private User user;  
  
    public UserRequest(User user) {  
        this.user = user;  
    }  
  
    public User getUser() {  
        return user;  
    }  
}  
  
// 支付请求  
class PaymentRequest implements Request {  
    private Payment payment;  
  
    public PaymentRequest(Payment payment) {  
        this.payment = payment;  
    }  
  
    public Payment getPayment() {  
        return payment;  
    }  
}  
  
// 地址请求  
class AddressRequest implements Request {  
    private Address address;  
  
    public AddressRequest(Address address) {  
        this.address = address;  
    }  
  
    public Address getAddress() {  
        return address;  
    }  
}  
  
// 用户类  
class User {  
    private boolean authenticated;  
  
    public User(boolean authenticated) {  
        this.authenticated = authenticated;  
    }  
  
    public boolean isAuthenticated() {  
        return authenticated;  
    }  
}  
  
// 支付类  
class Payment {  
    private boolean available;  
  
    public Payment(boolean available) {  
        this.available = available;  
    }  
  
    public boolean isAvailable() {  
        return available;  
    }  
}  
  
// 地址类  
class Address {  
    private boolean valid;  
  
    public Address(boolean valid) {  
        this.valid = valid;  
    }  
  
    public boolean isValid() {  
        return valid;  
    }  
}  
  
// 客户端调用案例  
public class Client {  
    public static void main(String[] args) {  
        // 创建责任链  
        Handler userHandler = new UserHandler();  
        Handler paymentHandler = new PaymentHandler();  
        Handler addressHandler = new AddressHandler();  
        userHandler.setSuccessor(paymentHandler);  
        paymentHandler.setSuccessor(addressHandler);  
  
        // 创建请求并发送给责任链  
        User user = new User(true);  
        Payment payment = new Payment(true);  
        Address address = new Address(true);  
  
        // 发送用户请求  
        userHandler.handleRequest(new UserRequest(user));  
  
        // 发送支付请求  
        userHandler.handleRequest(new PaymentRequest(payment));  
  
        // 发送地址请求  
        userHandler.handleRequest(new AddressRequest(address));  
  
        // 尝试使用无效用户发送请求  
        User invalidUser = new User(false);  
        userHandler.handleRequest(new UserRequest(invalidUser));  
    }  
}

在上述代码中,创建了三个具体处理者(UserHandler, PaymentHandler, AddressHandler),它们分别处理用户验证、支付验证和地址验证,每个处理者都实现了抽象处理者Handler定义的接口,并且可以在处理请求时将请求传递给链中的下一个处理者。

在client中创建了一个责任链,每个请求都被传递给链中的适当处理者,如果处理者能够处理该请求,则处理它,否则将其传递给下一个处理者,当客户端尝试使用无效用户发送请求时,用户验证处理者会捕获这个条件并输出错误消息,同时停止请求的进一步处理。

核心总结

程序员必知!责任链模式的实战应用与案例分析 - 程序员古德

责任链模式是一种行为设计模式,它允许对象对请求进行处理,或者将其传递给链中的下一个处理者,这种模式可以消除请求的发送者和接收者之间的耦合,它如下特点:

优点

  1. 降低耦合度:请求者不需要知道具体是哪个对象处理了请求,只需将请求发送到链上即可。
  2. 灵活性高:通过改变链内的成员或调整它们的顺序,可以动态地新增或删除责任。
  3. 明确各职责:每个处理者都清楚自己的职责,只处理自己感兴趣或能处理的请求。

缺点

  1. 请求可能得不到处理:如果链上的所有处理者都不处理请求,请求可能会直接结束,没有明确的反馈。
  2. 性能问题:对于长链或复杂处理,可能会导致处理时间增长,影响性能。
  3. 调试困难:由于请求可能在多个处理者之间传递,当出现问题时,定位问题可能会比较困难。

使用建议

  1. 在明确各处理者职责和处理顺序的情况下使用。
  2. 避免过长的责任链,以减少性能损失和调试难度。
  3. 当请求可能得不到处理时,应有相应的反馈或默认处理机制。

完!

关注我,每天学习互联网编程技术 - 程序员古德

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《程序员必知的硬核知识大全》是一本面向程序员的综合性知识手册,涵盖了各个领域的关键知识点,旨在帮助程序员提升技术水平和解决实际问题。该书以PDF格式出版,便于读者在电脑、手机等设备上随时查阅。 该书内容包括以下几个方面的硬核知识: 1. 编程语言知识:介绍了主流的编程语言,如Java、C++、Python等,包括语法、数据结构、算法等方面的内容。 2. 操作系统和计算机原理:详细介绍了操作系统的基本原理和常见问题解决方法,以及计算机组成原理和计算机网络等相关知识。 3. 数据库和存储知识:讲解了数据库设计和管理的基本原理,介绍了关系型数据库如MySQL和非关系型数据库如MongoDB等的使用方法和优化技巧。 4. 网站和网络开发知识:包括Web开发的基本原理、前后端开发技术、网络安全和性能优化等方面的内容。 5. 软件工程和开发方法论:介绍了软件工程的基本概念和常用开发方法,包括敏捷开发、测试驱动开发和持续集成等。 6. 设计模式和架构知识:详细介绍了常用的设计模式和软件架构,帮助程序员设计可维护、可扩展和高效的软件系统。 除了以上几个方面的内容,该书还涵盖了其他与程序员工作密切相关的技术和知识,如版本控制、软件部署、性能调优等。《程序员必知的硬核知识大全》适合本科或者有一定编程经验的程序员阅读,对于提高技术实力和职业发展都有很大帮助。 ### 回答2: "程序员必知的硬核知识大全 pdf"是一份提供程序员必备知识的电子书,PDF格式可以方便地在各种设备上阅读。这本书包含了各个方面的硬核知识,帮助程序员提高技术能力和解决问题的能力。 这本电子书的内容包括了数据结构和算法,编程语言,操作系统,网络通信,数据库管理等各方面的知识。对于程序员而言,这些都是非常重要的基础知识,能够帮助他们理解和设计高效的程序。 在数据结构和算法部分,程序员将学习到各种基础的数据结构,如数组、链表、栈和队列,以及常见的算法,如排序和搜索算法。这些知识对于程序的效率和性能优化至关重要。 编程语言部分将介绍多种编程语言,如C、C++、Java和Python等。这些语言在不同的领域有各自的优点和适用范围,程序员需要了解它们的特点和使用方法,以便在开发项目时选择合适的语言。 操作系统部分将深入讲解操作系统的原理和设计。程序员将了解到进程管理、内存管理、文件系统等重要概念,这些对于编写具有高可靠性和高性能的程序至关重要。 网络通信部分将介绍计算机网络的基本原理和常见的协议,如TCP/IP和HTTP等。程序员需要理解网络通信的基础知识,以便与其他系统进行数据交换和通信。 数据库管理部分将详细介绍关系型数据库和非关系型数据库的原理和使用方法。程序员需要了解数据库的设计和优化,以提高数据的存储和检索效率。 总之,这本电子书涵盖了程序员必备的硬核知识,对于提高他们的技术能力和解决问题的能力非常有帮助。 ### 回答3: 《程序员必知的硬核知识大全》是一本汇集了程序员必备的核心知识的书籍,可以帮助程序员提升自己的技术水平。这本书涵盖了计算机科学的各个领域和重要概念,包括数据结构与算法、操作系统、编程语言、网络通信、数据库、Web开发、软件工程等。 在数据结构与算法部分,书中介绍了常用的数据结构如链表、栈、队列以及各种排序和搜索算法,帮助程序员理解和应用这些经典的算法。在操作系统方面,书中讲解了进程、线程、内存管理、文件系统等重要概念,帮助程序员深入了解计算机系统的工作原理。 在编程语言方面,书中列举了多种编程语言的特性和应用场景,如C++、Java、Python等,有助于程序员选择适合自己的编程语言并掌握其特性。在网络通信部分,书中介绍了TCP/IP协议、HTTP协议等重要的网络通信协议和技术,帮助程序员理解网络通信的基本原理。 此外,书中还介绍了数据库的相关知识,包括关系数据库、SQL语言、数据备份与恢复等内容,有助于程序员设计和管理数据库。在Web开发方面,书中介绍了前端开发、后端开发、服务器部署等关键技术,帮助程序员构建高效、安全的Web应用程序。 最后,在软件工程方面,书中讲解了软件开发的生命周期、需求分析、设计模式、测试和持续集成等内容,有助于程序员理解和掌握软件开发过程中的重要环节。 总的来说,这本《程序员必知的硬核知识大全》提供了一站式的学习资料,涵盖了程序员必备的核心知识,可以帮助程序员系统地学习和应用这些知识,提升自己的技术能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员古德

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

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

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

打赏作者

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

抵扣说明:

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

余额充值