Java 设计模式西游篇 - 第七回:责任链模式过难关 通关文牒层层批

诗曰:

复制代码
审批流程似长链,层层传递不中断。
责任链模式来相助,通关文牒轻松办。

📖 故事

话说师徒四人来到"通关文牒岭",此地关卡重重,每过一关都要审批。

唐僧愁道:"悟空,这通关文牒如何办理?为师听说要经过十几道审批!"

悟空笑道:"师父莫急!徒儿用责任链模式,让文牒自动传递!"

🐉 踩坑打怪:审批混乱之劫

第一劫:硬编码审批链
java 复制代码
// 没有责任链,硬编码审批流程
public class PassportService {
    public void approvePassport(TangSeng tangSeng) {
        // 第一关:土地公审批
        LandGod landGod = new LandGod();
        if (!landGod.approve(tangSeng)) {
            System.out.println("土地公驳回!");
            return;
        }
        
        // 第二关:城隍审批
        CityGod cityGod = new CityGod();
        if (!cityGod.approve(tangSeng)) {
            System.out.println("城隍驳回!");
            return;
        }
        
        // 第三关:天王审批
        HeavenlyKing heavenlyKing = new HeavenlyKing();
        if (!heavenlyKing.approve(tangSeng)) {
            System.out.println("天王驳回!");
            return;
        }
        
        // 第四关:如来审批
        Rulai rulai = new Rulai();
        if (!rulai.approve(tangSeng)) {
            System.out.println("如来驳回!");
            return;
        }
        
        System.out.println("通关文牒办理成功!");
    }
}

八戒抱怨: "猴哥!这代码太长了!每加一个审批官,就要改代码!"

悟空点头: "正是!而且审批顺序写死了,想调整都难!"

第二劫:审批官耦合
java 复制代码
// 每个审批官都知道下一个审批官是谁
public class LandGod {
    public boolean approve(TangSeng tangSeng) {
        System.out.println("土地公审批中...");
        // 审批逻辑
        return true;
    }
}

public class CityGod {
    private LandGod landGod; // 依赖土地公
    
    public boolean approve(TangSeng tangSeng) {
        System.out.println("城隍审批中...");
        // 审批逻辑
        return landGod.approve(tangSeng); // 调用下一个
    }
}

沙僧发现: "大师兄!这样耦合太紧了!要是土地公请假了,城隍就没法工作了!"

⚔️ 责任链模式大法

第一步:定义处理者接口
java 复制代码
// 审批官接口
public interface Approver {
    void setNext(Approver next); // 设置下一个审批官
    boolean approve(TangSeng tangSeng); // 审批方法
}
第二步:实现抽象处理者
java 复制代码
// 抽象审批官
public abstract class AbstractApprover implements Approver {
    protected Approver next; // 下一个审批官
    
    @Override
    public void setNext(Approver next) {
        this.next = next;
    }
    
    @Override
    public boolean approve(TangSeng tangSeng) {
        // 子类实现具体审批逻辑
        if (next != null) {
            return next.approve(tangSeng); // 传递给下一个
        }
        return true; // 最后一个审批官,通过
    }
}
第三步:实现具体处理者
java 复制代码
// 土地公审批官
public class LandGodApprover extends AbstractApprover {
    @Override
    public boolean approve(TangSeng tangSeng) {
        System.out.println("【土地公】审批中...");
        
        // 审批逻辑:检查是否有犯罪记录
        if (tangSeng.hasCrimeRecord()) {
            System.out.println("【土地公】驳回:有犯罪记录!");
            return false;
        }
        
        System.out.println("【土地公】审批通过!");
        return super.approve(tangSeng); // 传递给下一个
    }
}

// 城隍审批官
public class CityGodApprover extends AbstractApprover {
    @Override
    public boolean approve(TangSeng tangSeng) {
        System.out.println("【城隍】审批中...");
        
        // 审批逻辑:检查是否有当地居住证
        if (!tangSeng.hasResidencePermit()) {
            System.out.println("【城隍】驳回:无居住证!");
            return false;
        }
        
        System.out.println("【城隍】审批通过!");
        return super.approve(tangSeng);
    }
}

// 天王审批官
public class HeavenlyKingApprover extends AbstractApprover {
    @Override
    public boolean approve(TangSeng tangSeng) {
        System.out.println("【托塔天王】审批中...");
        
        // 审批逻辑:检查是否有危险物品
        if (tangSeng.hasDangerousItems()) {
            System.out.println("【托塔天王】驳回:携带危险物品!");
            return false;        }
        
        System.out.println("【托塔天王】审批通过!");
        return super.approve(tangSeng);
    }
}

// 如来审批官(最终审批)
public class RulaiApprover extends AbstractApprover {
    @Override
    public boolean approve(TangSeng tangSeng) {
        System.out.println("【如来佛祖】最终审批中...");
        
        // 审批逻辑:综合评估
        if (tangSeng.getPurpose().equals("取经")) {
            System.out.println("【如来佛祖】审批通过!准予取经!");
            return true; // 最终审批,不传递给下一个
        } else {
            System.out.println("【如来佛祖】驳回:目的不纯!");
            return false;
        }
    }
}
第四步:组装责任链
java 复制代码
public class PassportChainBuilder {
    public static Approver buildChain() {
        // 创建审批官
        Approver landGod = new LandGodApprover();
        Approver cityGod = new CityGodApprover();
        Approver heavenlyKing = new HeavenlyKingApprover();
        Approver rulai = new RulaiApprover();
        
        // 组装责任链
        landGod.setNext(cityGod);
        cityGod.setNext(heavenlyKing);
        heavenlyKing.setNext(rulai);
        
        return landGod; // 返回链头
    }
}
第五步:实战演练
java 复制代码
public class Main {
    public static void main(String[] args) {
        // 构建审批链
        Approver chain = PassportChainBuilder.buildChain();
        
        // 唐僧申请通关文牒
        TangSeng tangSeng = new TangSeng();
        tangSeng.setPurpose("取经");
        tangSeng.setHasCrimeRecord(false);
        tangSeng.setHasResidencePermit(true);
        tangSeng.setHasDangerousItems(false);
        
        System.out.println("========== 开始审批 ==========");
        boolean approved = chain.approve(tangSeng);
        
        if (approved) {
            System.out.println("\n🎉 通关文牒办理成功!");
        } else {
            System.out.println("\n❌ 通关文牒被驳回!");
        }
        
        // 八戒申请(有犯罪记录)
        System.out.println("\n========== 八戒申请 ==========");
        TangSeng bajie = new TangSeng();
        bajie.setPurpose("旅游");
        bajie.setHasCrimeRecord(true); // 有犯罪记录
        bajie.setHasResidencePermit(false);
        bajie.setHasDangerousItems(false);
        
        boolean bajieApproved = chain.approve(bajie);
        System.out.println(bajieApproved ? "成功" : "被驳回");
    }
}

输出:

复制代码
========== 开始审批 ==========
【土地公】审批中...
【土地公】审批通过!
【城隍】审批中...
【城隍】审批通过!
【托塔天王】审批中...
【托塔天王】审批通过!
【如来佛祖】最终审批中...
【如来佛祖】审批通过!准予取经!

🎉 通关文牒办理成功!

========== 八戒申请 ==========
【土地公】审批中...
【土地公】驳回:有犯罪记录!

❌ 通关文牒被驳回!

🏆 战斗总结

唐僧赞叹: "悟空,这责任链模式果然精妙!审批流程清晰,加个审批官也方便!"

悟空得意: "师父,这还不止!咱们可以------"

优势 说明
解耦合 审批官之间互不知道
灵活组合 运行时动态组装链条
易于扩展 加新审批官不用改现有代码
职责清晰 每个审批官只负责自己的检查

本章要点

要点 说明
核心思想 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合
适用场景 审批流程、异常处理、过滤器链
优点 解耦合、灵活组合、易于扩展
缺点 可能无人处理、调试困难、性能问题

下回预告

话说师徒来到"女儿国",语言不通,如何交流?且看适配器模式!

欲知后事如何,且听第八回分解!


相关推荐
Lyyaoo.3 分钟前
【二分查找】【困难】寻找两个有序数组的中位数
java·数据结构·算法
小羊没烦恼!15 分钟前
Memory 记忆设计讨论:Agent Memory 的安全边界:权限、删除、版本与回执
java·大数据·word·powerpoint·.net
这是程序猿15 分钟前
Java线程池深度剖析:源码原理、核心参数、任务调度与生产调优实战
java·开发语言·python
rannn_11118 分钟前
【Java面试八股】Java基础篇|数据类型、面向对象、关键字、反射、注解、异常、新特性、序列化、设计模式、IO
java·后端·面试
MacroZheng27 分钟前
阿里又开源了一个神级 Skill 项目!
java·人工智能·后端
修罗-zero1 小时前
UI自动化开发(selenium):模拟人操作浏览器
java·selenium自动化
ruleslol1 小时前
Function Calling 讲解
java·ai
小小猪的春天1 小时前
MCP 半小时跑通和敢上生产之间,隔着这 5 个坑
java·ai编程
步行cgn1 小时前
Spring 注入 Properties 详解
java·python·spring
星空1 小时前
Map<String, String>`Map`是接口,不能直接 new
java·前端·算法