项目地址:https://gitee.com/caochenlei/design-pattern
责任链模式的介绍:
在现实生活中,一个事件需要经过多个对象处理是很常见的场景。例如,采购审批流程、请假流程等。公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据需要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这无疑增加了难度。
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
责任链模式的优点:
责任链模式的缺点:
责任链模式的场景:
责任链模式的角色:
采购员采购教学器材,请设计程序完成采购审批项目。
Approver
public abstract class Approver {
protected Approver approver;
protected String name;
public Approver(String name) {
this.name = name;
}
public Approver getNext() {
return approver;
}
public void setNext(Approver approver) {
this.approver = approver;
}
public abstract void handleRequest(PurchaseRequest purchaseRequest);
}
DepartmentApprover
//主任审批
public class DepartmentApprover extends Approver {
public DepartmentApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() < 0 && purchaseRequest.getPrice() <= 5000) {
System.out.println("本次采购请求被 " + this.name + " 处理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
DeanApprover
//院长审批
public class DeanApprover extends Approver {
public DeanApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() < 5000 && purchaseRequest.getPrice() <= 10000) {
System.out.println("本次采购请求被 " + this.name + " 处理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
ViceSchoolMasterApprover
//副校长审批
public class ViceSchoolMasterApprover extends Approver {
public ViceSchoolMasterApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {
System.out.println("本次采购请求被 " + this.name + " 处理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
SchoolMasterApprover
//校长审批
public class SchoolMasterApprover extends Approver {
public SchoolMasterApprover(String name) {
super(name);
}
@Override
public void handleRequest(PurchaseRequest purchaseRequest) {
if (purchaseRequest.getPrice() > 30000) {
System.out.println("本次采购请求被 " + this.name + " 处理");
} else {
if (this.approver != null) {
approver.handleRequest(purchaseRequest);
}
}
}
}
Client
public class Client {
public static void main(String[] args) {
//创建一个请求
PurchaseRequest purchaseRequest = new PurchaseRequest(31000);
//创建审批人员
DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
DeanApprover deanApprover = new DeanApprover("李院长");
ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");
SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("赵校长");
//设置审批链
departmentApprover.setNext(deanApprover);
deanApprover.setNext(viceSchoolMasterApprover);
viceSchoolMasterApprover.setNext(schoolMasterApprover);
//开始处理请求
departmentApprover.handleRequest(purchaseRequest);
}
}
本次采购请求被 赵校长 处理
在Java中,Servlet容器是责任链模式的经典应用。如在tomcat的包中,带有Filter、FilterChain结尾的类都是使用的是责任链模式。
javax.servlet.Filter
类使用的就是责任链模式来实现对请求的过滤,执行任一请求到资源过滤任务。源码如下:
public interface Filter {
public default void init(FilterConfig filterConfig)
throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
public default void destroy() {}
}
javax.Servlet.FilterChain
类也是通过责任链模式来进行过滤链中过滤器的调用。源码如下:
public interface FilterChain {
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException;
}
FilterChain是Servlet容器提供给开发人员的对象,它提供了对资源的已过滤请求的调用链的视图。过滤器使用FilterChain调用链中的下一个过滤器,或者调用过滤器是链中的最后一个过滤器。
工具:Eclipse,Oracle,smartupload.jar;语言:jsp,Java;数据存储:Oracle。...
Elasticsearch 是通过 Lucene 的倒排索引技术实现比关系型数据库更快的过滤。特...
本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如...
DELETEFROMTablesWHEREIDNOTIN(SELECTMin(ID)FROMTablesGROUPBYName) Min的话保...
4月11日20:30~22:00通过腾讯会议进行了第二次在线学习讨论我把学习笔记整理一下...
正则忽略大小写 – RegexOptions.IgnoreCase 例如: 复制代码 代码如下: Str = R...
复制代码 代码如下: % URL="http://news.163.com/special/00011K6L/rss_newstop....
错误描述: 在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报...
上篇文章给大家介绍了 Java正则表达式匹配,替换,查找,切割的方法 ,接下来,...
项目中用到的一些特殊字符和图标 html代码 XML/HTML Code 复制内容到剪贴板 div ...