设计模式最佳实践 - 模板模式 + 责任链模式
废话不多说,直接切入正题,本篇要讲的是 模板模式 + 责任链模式 实践。
该最佳实践本身就是一种对 责任链模式的增强,模板模式通过 父类 强耦合,预定义好 责任链 next 方法 的前后一些切面行为,优雅简洁。
先上示例,单独责任链模式 简单示例如下:
// 请假请求类
class LeaveRequest {private String employeeName;private int days;public LeaveRequest(String employeeName, int days) {this.employeeName = employeeName;this.days = days;}public String getEmployeeName() {return employeeName;}public int getDays() {return days;}
}// 抽象处理者
abstract class Approver {protected Approver nextApprover;public Approver(Approver nextApprover) {this.nextApprover = nextApprover;}public abstract void approve(LeaveRequest request);
}// 具体处理者:组长,处理1-3天的请假
class TeamLeader extends Approver {public TeamLeader(Approver nextApprover) {super(nextApprover);}@Overridepublic void approve(LeaveRequest request) {if (request.getDays() <= 3) {System.out.println("组长批准了" + request.getEmployeeName() + "的" + request.getDays() + "天假期");} else if (nextApprover != null) {nextApprover.approve(request);}}
}// 具体处理者:部门经理,处理4-7天的请假
class DepartmentManager extends Approver {public DepartmentManager(Approver nextApprover) {super(nextApprover);}@Overridepublic void approve(LeaveRequest request) {if (request.getDays() > 3 && request.getDays() <= 7) {System.out.println("部门经理批准了" + request.getEmployeeName() + "的" + request.getDays() + "天假期");} else if (nextApprover != null) {nextApprover.approve(request);}}
}// 具体处理者:总经理,处理8天及以上的请假
class GeneralManager extends Approver {public GeneralManager(Approver nextApprover) {super(nextApprover);}@Overridepublic void approve(LeaveRequest request) {if (request.getDays() > 7) {System.out.println("总经理批准了" + request.getEmployeeName() + "的" + request.getDays() + "天假期");} else if (nextApprover != null) {nextApprover.approve(request);}}
}// 演示类
public class LeaveApprovalDemo {public static void main(String[] args) {// 构建责任链Approver generalManager = new GeneralManager(null);Approver departmentManager = new DepartmentManager(generalManager);Approver teamLeader = new TeamLeader(departmentManager);// 创建请假请求LeaveRequest request1 = new LeaveRequest("张三", 2);LeaveRequest request2 = new LeaveRequest("李四", 5);LeaveRequest request3 = new LeaveRequest("王五", 10);// 处理请求teamLeader.approve(request1);teamLeader.approve(request2);teamLeader.approve(request3);}
}
当需求增加,每个子类责任链都需要有额外的功能,比如 处理请假请求前,需要 看一下手表,就可以在父类抽取 出方法,子类只需要实现核心逻辑,前后切面逻辑父类通过模板模式预定义,不仅耦合性低,重用性也极高,如需要更改父类前后逻辑,直接进行重写即可,加上模板模式后,示例如下:
// 请假请求类
class LeaveRequest {private String employeeName;private int days;private String reason;public LeaveRequest(String employeeName, int days, String reason) {this.employeeName = employeeName;this.days = days;this.reason = reason;}public String getEmployeeName() {return employeeName;}public int getDays() {return days;}public String getReason() {return reason;}
}// 抽象处理者 - 结合了模板模式
abstract class Approver {protected Approver nextApprover;protected String approverTitle; // 审批者头衔public Approver(String approverTitle, Approver nextApprover) {this.approverTitle = approverTitle;this.nextApprover = nextApprover;}// 模板方法:定义审批流程的骨架public final void processRequest(LeaveRequest request) {// 1. 前置处理beforeApproval(request);// 2. 核心审批逻辑(由子类实现)boolean handled = handleApproval(request);// 3. 后置处理afterApproval(request, handled);// 4. 如果当前处理者不能处理,传递给下一个if (!handled && nextApprover != null) {nextApprover.processRequest(request);}}// 前置处理 - 模板中的固定步骤protected void beforeApproval(LeaveRequest request) {System.out.println("\n===== 开始处理 " + request.getEmployeeName() + " 的请假申请 =====");System.out.println("请假天数: " + request.getDays() + "天");System.out.println("请假原因: " + request.getReason());System.out.println("当前审批者: " + approverTitle);}// 后置处理 - 模板中的固定步骤protected void afterApproval(LeaveRequest request, boolean handled) {if (handled) {System.out.println(approverTitle + "已批准该请假申请");System.out.println("===== " + request.getEmployeeName() + " 的请假申请处理完毕 =====");} else {System.out.println(approverTitle + "无法处理,将提交给上一级审批");}}// 抽象方法:具体审批逻辑由子类实现protected abstract boolean handleApproval(LeaveRequest request);
}// 具体处理者:组长,处理1-3天的请假
class TeamLeader extends Approver {public TeamLeader(Approver nextApprover) {super("组长", nextApprover);}@Overrideprotected boolean handleApproval(LeaveRequest request) {if (request.getDays() <= 3) {// 组长特有的审批逻辑System.out.println("组长审批:请假天数在权限范围内,直接批准");return true;}return false;}
}// 具体处理者:部门经理,处理4-7天的请假
class DepartmentManager extends Approver {public DepartmentManager(Approver nextApprover) {super("部门经理", nextApprover);}@Overrideprotected boolean handleApproval(LeaveRequest request) {if (request.getDays() > 3 && request.getDays() <= 7) {// 部门经理特有的审批逻辑System.out.println("部门经理审批:已核实工作安排,可批准请假");return true;}return false;}
}// 具体处理者:总经理,处理8天及以上的请假
class GeneralManager extends Approver {public GeneralManager(Approver nextApprover) {super("总经理", nextApprover);}@Overrideprotected boolean handleApproval(LeaveRequest request) {if (request.getDays() > 7) {// 总经理特有的审批逻辑System.out.println("总经理审批:已评估项目进度,批准长假申请");return true;}return false;}
}// 演示类
public class EnhancedLeaveApprovalDemo {public static void main(String[] args) {// 构建责任链Approver generalManager = new GeneralManager(null);Approver departmentManager = new DepartmentManager(generalManager);Approver teamLeader = new TeamLeader(departmentManager);// 创建请假请求LeaveRequest request1 = new LeaveRequest("张三", 2, "个人身体不适");LeaveRequest request2 = new LeaveRequest("李四", 5, "家中有事需要处理");LeaveRequest request3 = new LeaveRequest("王五", 10, "计划休年假旅游");// 处理请求teamLeader.processRequest(request1);teamLeader.processRequest(request2);teamLeader.processRequest(request3);}
}