设计模式简单说明:责任链与规则树
文章目录
- 前言
- 一、责任链模式实现
- 1.1 责任链模式概述
- 1.2 代码实现
- 1.2.1 车辆检查上下文对象
- 1.2.2 抽象检查处理器
- 1.2.3 具体处理器:保险检查
- 1.2.4 具体处理器:维护记录检查
- 1.2.5 具体处理器:安全检查
- 1.3 测试责任链模式
- 二、规则树实现
- 2.1 规则树概述
- 2.2 代码实现
- 2.2.1 车辆检查上下文对象
- 2.2.2 规则接口
- 2.2.3 叶子规则:基础条件规则
- 2.2.4 具体叶子规则:保险规则
- 2.2.5 具体叶子规则:维护规则
- 2.2.6 具体叶子规则:安全证书规则
- 2.2.7 复合规则:所有子规则必须全部通过(与规则)
- 2.2.8 复合规则:至少一个子规则通过(或规则)
- 2.2.9 规则树执行器
- 2.3 测试规则树模式
- 三、两种模式对比与应用场景
- 3.1 责任链模式 vs 规则树(组合模式)对比
- 3.2 在物流系统中的综合应用
- 总结
前言
在物流车辆管理系统中,我们经常需要处理复杂的业务规则和校验流程。例如,车辆调度前的资格审核、运输途中的状态检查、到货后的验收流程等。这些业务场景通常包含多个按顺序或条件执行的规则。本文将介绍如何使用责任链模式和规则树(基于组合模式)来优雅地处理这些复杂逻辑,并提供完整的代码实现和测试。
一、责任链模式实现
1.1 责任链模式概述
责任链模式(Chain of Responsibility)是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下一个处理者。
在物流系统中,我们可以使用责任链模式来处理车辆出车前的多级审批流程。
1.2 代码实现
1.2.1 车辆检查上下文对象
// 车辆检查上下文对象
public class VehicleCheckContext {private String vehicleId;private boolean hasValidInsurance=true;//车辆保险private boolean hasMaintenanceRecord=true;//维修记录private boolean hasSafetyCertificate=true;//安全检查public VehicleCheckContext(String vehicleId, boolean hasValidInsurance, boolean hasMaintenanceRecord,boolean hasSafetyCertificate) {this.vehicleId = vehicleId;this.hasValidInsurance = hasValidInsurance;this.hasMaintenanceRecord = hasMaintenanceRecord;this.hasSafetyCertificate = hasSafetyCertificate;}public boolean isHasValidInsurance() {return hasValidInsurance;}public void setHasValidInsurance(boolean hasValidInsurance) {this.hasValidInsurance = hasValidInsurance;}public boolean isHasMaintenanceRecord() {return hasMaintenanceRecord;}public void setHasMaintenanceRecord(boolean hasMaintenanceRecord) {this.hasMaintenanceRecord = hasMaintenanceRecord;}public boolean isHasSafetyCertificate() {return hasSafetyCertificate;}public void setHasSafetyCertificate(boolean hasSafetyCertificate) {this.hasSafetyCertificate = hasSafetyCertificate;}public String getVehicleId() {return vehicleId;}public void setVehicleId(String vehicleId) {this.vehicleId = vehicleId;}
}
1.2.2 抽象检查处理器
// 抽象检查处理器
abstract class VehicleCheckHandler {protected VehicleCheckHandler nextHandler;public VehicleCheckHandler setNextHandler(VehicleCheckHandler nextHandler) {this.nextHandler = nextHandler;return nextHandler;}public abstract void check(VehicleCheckContext context);//抽象检查方法protected void checkNext(VehicleCheckContext context) {if (nextHandler != null) {nextHandler.check(context);}}
}
1.2.3 具体处理器:保险检查
// 具体处理器:保险检查
public class InsuranceCheckHandler extends VehicleCheckHandler{@Overridepublic void check(VehicleCheckContext context) {System.out.println("检查车辆 " + context.getVehicleId() + " 的保险状态...");if(!context.isHasValidInsurance()){//检查未通过System.out.println("❌ 保险检查未通过:车辆保险已过期");return; // 终止链条}System.out.println("✅ 保险检查通过");checkNext(context);}
}
1.2.4 具体处理器:维护记录检查
// 具体处理器:维护记录检查
public class MaintenanceCheckHandler extends VehicleCheckHandler {@Overridepublic void check(VehicleCheckContext context) {System.out.println("检查车辆 " + context.getVehicleId() + " 的维护记录...");if (!context.isHasMaintenanceRecord()) {//维护记录检查未通过System.out.println("❌ 维护记录检查未通过:缺少最近3个月的维护记录");return; // 终止链条}System.out.println("✅ 维护记录检查通过");checkNext(context);}
}
1.2.5 具体处理器:安全检查
// 具体处理器:安全检查
public class SafetyCheckHandler extends VehicleCheckHandler{@Overridepublic void check(VehicleCheckContext context) {System.out.println("检查车辆 " + context.getVehicleId() + " 的安全证书...");if(!context.isHasSafetyCertificate()){//安全校验不通过System.out.println("❌ 安全检查未通过:安全证书已过期");return; // 终止链条}System.out.println("✅ 安全检查通过");checkNext(context);}
}
1.3 测试责任链模式
public class Client {public static void main(String[] args) {//创建责任链InsuranceCheckHandler insuranceCheckHandler = new InsuranceCheckHandler();insuranceCheckHandler.setNextHandler(new MaintenanceCheckHandler()).setNextHandler(new SafetyCheckHandler());//设置责任链执行顺序//创建车辆检查上下文VehicleCheckContext context = new VehicleCheckContext("京A12345", true,false, true);//设置维修状态为falseSystem.out.println("开始车辆出车前检查流程...\n");//启动责任链insuranceCheckHandler.check(context);System.out.println("\n检查流程结束\n");//创建车辆检查上下文context = new VehicleCheckContext("京A666666", true,true, true);System.out.println("开始车辆出车前检查流程...\n");//启动责任链insuranceCheckHandler.check(context);System.out.println("\n检查流程结束");}
}
二、规则树实现
2.1 规则树概述
规则树是一种更复杂的规则处理结构,基于组合模式(Composite Pattern)实现。它允许我们创建复杂的树形结构规则,其中节点可以是叶子节点(简单规则)或复合节点(包含子规则的规则)。
在物流系统中,规则树可以用于处理更复杂的条件逻辑,如:“如果车辆类型是冷藏车且运输的是生鲜食品,那么必须检查制冷系统且温度记录正常”。
2.2 代码实现
2.2.1 车辆检查上下文对象
// 车辆检查上下文对象
public class VehicleCheckContext {private String vehicleId;private boolean hasValidInsurance=true;//车辆保险private boolean hasMaintenanceRecord=true;//维修记录private boolean hasSafetyCertificate=true;//安全检查public VehicleCheckContext(String vehicleId, boolean hasValidInsurance, boolean hasMaintenanceRecord,boolean hasSafetyCertificate) {this.vehicleId = vehicleId;this.hasValidInsurance = hasValidInsurance;this.hasMaintenanceRecord = hasMaintenanceRecord;this.hasSafetyCertificate = hasSafetyCertificate;}public boolean isHasValidInsurance() {return hasValidInsurance;}public void setHasValidInsurance(boolean hasValidInsurance) {this.hasValidInsurance = hasValidInsurance;}public boolean isHasMaintenanceRecord() {return hasMaintenanceRecord;}public void setHasMaintenanceRecord(boolean hasMaintenanceRecord) {this.hasMaintenanceRecord = hasMaintenanceRecord;}public boolean isHasSafetyCertificate() {return hasSafetyCertificate;}public void setHasSafetyCertificate(boolean hasSafetyCertificate) {this.hasSafetyCertificate = hasSafetyCertificate;}public String getVehicleId() {return vehicleId;}public void setVehicleId(String vehicleId) {this.vehicleId = vehicleId;}
}
2.2.2 规则接口
// 规则接口
public interface Rule {boolean evaluate(VehicleCheckContext context);//规则检查逻辑String getDescription();//获取规则描述
}
2.2.3 叶子规则:基础条件规则
// 叶子规则:基础条件规则
abstract class BaseRule implements Rule {protected String description;public String getDescription() {return description;}
}
2.2.4 具体叶子规则:保险规则
// 具体叶子规则:保险规则
public class InsuranceRule extends BaseRule{public InsuranceRule(){this.description = "车辆保险有效";}@Overridepublic boolean evaluate(VehicleCheckContext context) {return context.isHasValidInsurance();}
}
2.2.5 具体叶子规则:维护规则
// 具体叶子规则:维护规则
public class MaintenanceRule extends BaseRule{public MaintenanceRule(){this.description = "有近期维护记录";}@Overridepublic boolean evaluate(VehicleCheckContext context) {return context.isHasMaintenanceRecord();}
}
2.2.6 具体叶子规则:安全证书规则
// 具体叶子规则:安全证书规则
public class SafetyRule extends BaseRule{public SafetyRule(){this.description = "安全证书有效";}@Overridepublic boolean evaluate(VehicleCheckContext context) {return context.isHasSafetyCertificate();}
}
2.2.7 复合规则:所有子规则必须全部通过(与规则)
import java.util.List;
// 复合规则:所有子规则必须全部通过(与规则)
public class AllOfRule extends BaseRule {private List<Rule> rules;public AllOfRule(String description, List<Rule> rules) {this.description = description;this.rules = rules;}@Overridepublic boolean evaluate(VehicleCheckContext context) {for (Rule rule : rules) {if (!rule.evaluate(context)) {return false;}}return true;}
}
2.2.8 复合规则:至少一个子规则通过(或规则)
import java.util.List;// 复合规则:至少一个子规则通过(或规则)
public class AnyOfRule extends BaseRule {private List<Rule> rules;public AnyOfRule(String description, List<Rule> rules) {this.description = description;this.rules = rules;}@Overridepublic boolean evaluate(VehicleCheckContext context) {for (Rule rule : rules) {if (rule.evaluate(context)) {return true;}}return false;}
}
2.2.9 规则树执行器
- 方便组合
// 规则树执行器
public class RuleEngine {public static boolean checkRules(Rule rootRule, VehicleCheckContext context) {System.out.println("执行规则检查: " + rootRule.getDescription());boolean result = rootRule.evaluate(context);System.out.println("规则检查结果: " + (result ? "✅ 通过" : "❌ 未通过"));return result;}
}
2.3 测试规则树模式
import java.util.Arrays;public class Client {public static void main(String[] args) {//创建规则Rule insurance=new InsuranceRule();Rule maintenance=new MaintenanceRule();Rule safety=new SafetyRule();//创建复合规则//与规则Rule all=new AllOfRule("与规则", Arrays.asList(insurance,maintenance,safety));//或规则Rule any=new AnyOfRule("或规则", Arrays.asList(insurance,maintenance,safety));//创建车辆上下文内容//创建车辆检查上下文VehicleCheckContext context = new VehicleCheckContext("京A12345", true,false, true);//设置维修状态为falseSystem.out.println("=== 测试用例1: 所有检查通过 ===");boolean result1 = RuleEngine.checkRules(all, context);System.out.println("最终结果: " + (result1 ? "✅ 车辆允许出车" : "❌ 车辆不允许出车"));System.out.println("\n=== 测试用例2: 维护记录检查失败 ===");boolean result2 = RuleEngine.checkRules(any, context);System.out.println("最终结果: " + (result2 ? "✅ 车辆允许出车" : "❌ 车辆不允许出车"));}
}
三、两种模式对比与应用场景
3.1 责任链模式 vs 规则树(组合模式)对比
特性 | 责任链模式 | 规则树(组合模式) |
---|---|---|
结构 | 线性链式结构 | 树形嵌套结构 |
处理逻辑 | 请求沿链单向传递 | 递归遍历树节点 |
节点关系 | 平级处理器 | 父子层级关系 |
动态修改 | 支持动态调整处理器顺序 | 支持动态增删子树 |
终止机制 | 任一处理器可中断流程 | 依赖条件判断决定递归路径 |
典型应用 | 审批流程、验证链等需要按顺序执行且可能提前终止的场景 | 复杂业务规则引擎、决策树等需要灵活组合规则的场景 |
3.2 在物流系统中的综合应用
在实际的物流车辆管理系统中,我们可以结合使用这两种模式:
// 综合应用示例
public class LogisticsVehicleManager {private VehicleCheckHandler checkHandlerChain;private Rule criticalRules;public LogisticsVehicleManager() {// 初始化责任链checkHandlerChain = new InsuranceCheckHandler();checkHandlerChain.setNextHandler(new MaintenanceCheckHandler()).setNextHandler(new SafetyCheckHandler());// 初始化关键规则树Rule insuranceRule = new InsuranceRule();Rule safetyRule = new SafetyRule();criticalRules = new AllOfRule("关键安全规则", Arrays.asList(insuranceRule, safetyRule));}public boolean approveVehicleDispatch(String vehicleId) {// 从数据库加载车辆信息VehicleCheckContext context = loadVehicleContext(vehicleId);System.out.println("执行责任链检查...");// 使用责任链执行详细检查流程checkHandlerChain.check(context);System.out.println("\n执行关键规则验证...");// 使用规则树验证关键规则boolean criticalRulesPassed = RuleEngine.checkRules(criticalRules, context);return criticalRulesPassed;}private VehicleCheckContext loadVehicleContext(String vehicleId) {// 实际项目中应从数据库加载车辆信息// 这里简化为硬编码值return new VehicleCheckContext(vehicleId, true, true, true);}public static void main(String[] args) {LogisticsVehicleManager manager = new LogisticsVehicleManager();boolean approved = manager.approveVehicleDispatch("京A12345");System.out.println("\n车辆调度审批结果: " + (approved ? "✅ 批准" : "❌ 拒绝"));}
}
总结
在实际项目中,推荐优先使用责任链模式处理流程性业务,因其结构简单易懂,易于维护。当业务规则变得复杂,需要支持多种条件组合时,再引入规则树模式。对于大型系统,往往需要结合使用两种模式,用责任链定义主流程,用规则树处理复杂决策点。
通过这种设计模式的应用,我们可以创建出更加灵活、可维护和可扩展的业务规则处理系统,提高代码质量和开发效率。