当前位置:主页 > 查看内容

设计模式:行为型-责任链模式

发布时间:2021-06-17 00:00| 位朋友查看

简介:目录 第一章 责任链模式介绍 第二章 责任链模式实现 2.1、抽象处理者 2.2、具体处理者 2.3、最终测试类 第三章 责任链模式应用 项目地址https://gitee.com/caochenlei/design-pattern 第一章 责任链模式介绍 责任链模式的介绍 在现实生活中一个事件需要经过……


项目地址:https://gitee.com/caochenlei/design-pattern

第一章 责任链模式介绍

责任链模式的介绍:

在现实生活中,一个事件需要经过多个对象处理是很常见的场景。例如,采购审批流程、请假流程等。公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据需要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这无疑增加了难度。

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

责任链模式的优点:

  • 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
  • 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
  • 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
  • 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
  • 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

责任链模式的缺点:

  • 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

责任链模式的场景:

  • 多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定。
  • 可动态指定一组对象处理请求,或添加新的处理者。
  • 需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

责任链模式的角色:

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

第二章 责任链模式实现

采购员采购教学器材,请设计程序完成采购审批项目。

    1. 如果金额小于等于 5000,由主任审批 (0<=x<=5000)
    1. 如果金额小于等于 10000,由院长审批(5000<x<=10000)
    1. 如果金额小于等于 30000,由副校长审批(10000<x<=30000)
    1. 如果金额超过 30000 以上,有校长审批(30000<x)

2.1、抽象处理者

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);
}

2.2、具体处理者

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);
            }
        }
    }
}

2.3、最终测试类

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调用链中的下一个过滤器,或者调用过滤器是链中的最后一个过滤器。

;原文链接:https://blog.csdn.net/qq_38490457/article/details/115606464
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐