设计模式——责任链模式

    xiaoxiao2021-03-25  80

    模式介绍

    责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

    模式的优缺点

    优点

    1.因为客户端的请求不知道会被哪个对象处理,所以系统的更改可以在不影响客户端的情况下动态的重新组织和分配责任,这样灵活性很强。 2.请求发送者不知道请求会被哪个接收对象处理,且链中的对象也不用关心链的结构,只需要保持一个指向其后继者的引用,这样大大降低了耦合度。

    缺点

    缺点是没有明确的接收者,可能传到链的最后,也没得到正确的处理。

    模式结构

    模式涉及角色

    抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。

    具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

    结构图

    示例

    场景

    员工请假,请假天数不超过3天,经理可以审批;请假天数超过3天但不超过10天,需要总监批准;请假天数超过10天则需要总经理审批。

    类结构分析

    请假类:LeaveRequest 包含名称,请假时间和原因。 管理者抽象类:包含处理请假请求的抽象方法和指定上级的方法。 具体的管理者:实现对请假请求的处理,这里包括继承了管理这抽象类的经理类,总监类和总经理类。

    代码实现

    /** * 责任链模式 * Created by gary on 2017/3/11. */ public class ResponsibilityChainModel { public static void main(String[] args){ LeaveRequest leaveRequest = new LeaveRequest("小刘", 12, "旅游"); CommonManager commonManager = new CommonManager("张三"); Director director = new Director("李四"); GeneralManager generalManager = new GeneralManager("王五"); //指定上级关系 commonManager.setSuperior(director); director.setSuperior(generalManager); commonManager.handleRequest(leaveRequest); } } /** * 请假请求类 */ class LeaveRequest{ private String name; private int leaveDays; private String reason; public LeaveRequest(String name, int leaveDays, String reason){ this.name = name; this.leaveDays = leaveDays; this.reason = reason; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getLeaveDays() { return leaveDays; } public void setLeaveDays(int leaveDays) { this.leaveDays = leaveDays; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } } /** * 管理者抽象类 */ abstract class Manager{ protected String name; protected Manager superior; public Manager(String name){ this.name = name; } /** * 处理请假抽象方法 */ public abstract void handleRequest(LeaveRequest leaveRequest); public void setSuperior(Manager superior){ this.superior = superior; } } /** * 经理类,能处理不超过3天的假期 */ class CommonManager extends Manager{ public CommonManager(String name){ super(name); } public void handleRequest(LeaveRequest leaveRequest){ int leaveDays = leaveRequest.getLeaveDays(); if(leaveDays <= 3){ System.out.println("经理" + name + "批准"); }else{ System.out.println("请假超过3天,经理无法处理,交由上级审批"); if(superior != null){ superior.handleRequest(leaveRequest); } } } } /** * 总监类,能处理超过三天但不超过十天的假期 */ class Director extends Manager{ public Director(String name){ super(name); } public void handleRequest(LeaveRequest leaveRequest){ int leaveDays = leaveRequest.getLeaveDays(); if(leaveDays > 3 && leaveDays <= 10){ System.out.println("总监批准"); }else{ System.out.println("请假超过10天,总监无法处理,交由上级审批"); if(superior != null){ superior.handleRequest(leaveRequest); } } } } /** * 总经理类,能处理超过10天以上的假期 */ class GeneralManager extends Manager{ public GeneralManager(String name){ super(name); } public void handleRequest(LeaveRequest leaveRequest){ int leaveDays = leaveRequest.getLeaveDays(); if(leaveDays > 10){ System.out.println("总经理批准"); }else{ if(superior != null){ superior.handleRequest(leaveRequest); } } } }

    运行结果:

    请假超过3天,经理无法处理,交由上级审批 请假超过10天,总监无法处理,交由上级审批 总经理批准

    应用场景

    java的异常处理,比如异常链;Tomcat中的Filter也使用了责任链模式

    项目中的应用

    如果一个类要么承担责任处理请求要么将请求传递给下个对象处理,则被称为纯责任链模式。 如果一个类承担了一部分责任,继续将请求传递给下个对象处理,则被称为不纯的责任链模式。

    项目中可能使用不纯的责任链模式多一些,比如项目中可以把链中的对象做成可配置化,写到配置文件中,这样可以动态指定对那些请求做什么样的处理。

    参考资料

    《JAVA与模式》之责任链模式 《大话设计模式》

    转载请注明原文地址: https://ju.6miu.com/read-33368.html

    最新回复(0)