聊聊设计模式中的责任链模式

本文通过一个案例展示了如何使用责任链模式来优化客户端向服务端发送请求的业务流程,实现模块解耦和自由组合。在原有代码中,随着业务需求增加,代码变得难以维护。通过引入责任链模式,将用户认证、Session缓存和业务处理等模块分离,实现了模块的独立和按需组合,提高了代码的复用性和可维护性。然而,这种模式也可能导致链过长影响性能,并增加客户端代码复杂度。适用场景包括需要多步骤审批或处理的业务流程。
摘要由CSDN通过智能技术生成

简述

将各个功能拆分后分别封装(各功能解耦),需要时可自由组合(包括执行顺序)

话不多说,看个优化案例吧。

优化案例

最初版

以下是模拟客户端想服务端发送请求的业务流程。

客户端调用代码如下。

// 客户端public class Client { public static void main(String[] args) { Map<String, String> request = new HashMap<>(); request.put("username", "admin"); request.put("password", "admin"); service(request); } public static void service(Map<String, String> request) { String username = request.get("username"); String password = request.get("password"); if (!"admin".equals(username) || !"admin".equals(password)) { throw new RuntimeException("用户名或密码不正确!"); } System.out.println("用户认证通过。"); System.out.println("正在处理请求的业务。"); }}

如果根据新的需求,需要在用户认证通过到处理请求的业务之间增加一个缓存用户信息至Session的处理该怎么办,传统的写法肯定是直接在上述代码的第14行后加入一条缓存用户信息的处理,但这样下去,以后每次增加这部分的需求是都无一例外的需要修改客户端的代码,并且实际上客户端发送请求的方法肯定不止一处,如果有一个新业务是需要在每个请求的方法中都添加呢。那又怎么办?现在上面的代码只是模拟,所以只需要加一行打印输出即可,真实的逻辑可比这复杂得多,到时候的代码量也是现在的好几倍,岂不麻烦死了?

为了解决这个问题,我们可以使用责任链模式。

修改版v1

增加一组类,使用责任链模式。如下。

// 责任链的顶级接口// 定义责任链的核心功能public interface Chain { // 指定下一个处理 void setNext(Chain next); // 处理当前请求 void handler(Map<String, String> request);}// 责任链的抽象父类// 定义所有责任链对象共通的属性和方法public abstract class AbstractChain implements Chain { // 持有下一个处理 private Chain next; public Chain getNext() { return next; } @Override public void setNext(Chain next) { this.next = next; }}// 用户认证模块public class AuthChain extends AbstractChain { @Override public void handler(Map<String, String> request) { String username = request.get("username"); String password = request.get("password"); if (!"admin".equals(username) || !"admin".equals(password)) { throw new RuntimeException("用户名或密码不正确!"); } System.out.println("用户认证通过。"); Chain next = this.getNext(); if (next == null) { throw new RuntimeException("处理中断!"); } next.handler(request); }}// Session缓存模块public class SessionChain extends AbstractChain { @Override public void handler(Map<String, String> request) { System.out.println("缓存用户信息至Session。"); Chain next = this.getNext(); if (next == null) { throw new RuntimeException("处理中断!"); } next.handler(request); }}// 业务处理模块public class ProcessChain extends AbstractChain { @Override public void handler(Map<String, String> request) { System.out.println("正在处理请求的业务。"); }}

修改后,客户端代码的调用如下。

public class Client { public static void main(String[] args) { Map<String, String> request = new HashMap<>(); request.put("username", "admin"); request.put("password", "admin"); service(request); } public static void service(Map<String, String> request) { Chain auth = new AuthChain(); Chain session = new SessionChain(); Chain process = new ProcessChain(); auth.setNext(session); session.setNext(process); auth.handler(request); }}

熟悉数据结构的同学肯定一眼就看出了责任链模式的本质:链表。将一个冗长的业务处理流程拆分成各个模块,使用时根据业务流程以链表的形式将其串联。不仅提升了各个模块代码的复用性,而且还能是的各个模块自由组合,极大的提升了开发效率。

总结

优点

  • 可以自由指定各个模块的执行顺序。

  • 各个模块遵循单一职责使得各个模块间解耦。

  • 新增业务流程时只需要增加新的模块即可,遵循开闭原则,提升了系统的可维护性。

缺点

  • 当业务流程过长时,组成的业务链也会非常的长,涉及到的对象过多可能会影响系统的性能。

  • 虽然各个模块可以自由组合,但是组合的工作实际上都放在了客户端,这无疑提升了客户端的代码复杂度。

适用场景

  • 业务流程类的功能都可以使用责任链模式。公司或政府部门各级对于文件的审批,需要各级各部门盖章签字,并且其中一环未通过就得打回重新审核。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值