责任链模式
定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有对象处理它为止。
优缺点
优点
能将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦提高系统的灵活性
缺点
- 性能问题,每个请求都是从链头遍历到链尾,尤其是链较长的时候,会有性能方面的影响。
- 调试不方便,由于采用了类似递归的方式(本实验用的是队列的遍历),调试的时候会比较复杂。
实验小结
- 即一个任务到来时,进入责任链,从头开始遍历责任人,不是则依次往下寻找,直到找到负责该任务的责任人(可能无人负责)
- 将责任链节点依次加入队列就能build()出责任链关系。
代码模拟场景
项目进入测试阶段,项目组出现问题,依次寻找测试、开发、产品经理寻求帮助。
责任链模式
UML图
责任链节点抽象、实现类
public abstract class AbstractHandler {/*** 测试处理等级*/public final static int TEST_LEVEL_REQUEST = 1;/*** 开发处理等级*/public final static int DEVELOPER_LEVEL_REQUEST = 2;/*** 产品经理处理等级*/public final static int PRODUCT_MANAGER_LEVEL_REQUEST = 3;/*** 能处理的级别*/private final int level;/*** 责任传递,下个责任人是谁*/private AbstractHandler nextHandler;/*** 每个责任节点都要说明下自己能处理哪些需求** @param level 处理等级*/public AbstractHandler(int level) {this.level = level;}/*** 处理项目的要求** @param project 项目需要*/public final void handleMessage(IProject project) {if (project.getType() == this.level) {this.response(project);} else {// 后续有环节则继续推进请求if (this.nextHandler != null) {this.nextHandler.handleMessage(project);} else {System.out.println("已无流程批示,不同意");}}}/*** 传递给下个处理人** @param handler 下个处理人*/public void setNext(AbstractHandler handler) {this.nextHandler = handler;}/*** 处理人的回应** @param project 项目对象*/protected abstract void response(IProject project);
}/*** @author Evad.Wu* @Description 测试工程师* @date 2023-07-10*/
public class TestEngineer extends AbstractHandler {/*** 每个责任节点都要说明下自己能处理哪些需求*/public TestEngineer() {super(AbstractHandler.TEST_LEVEL_REQUEST);}@Overrideprotected void response(IProject project) {System.out.println("项目组向测试人员咨询");System.out.println(project.getRequest());System.out.println("测试人员的答复是:找我就对了");}
}/*** @author Evad.Wu* @Description 开发工程师* @date 2023-07-10*/
public class DevelopmentEngineer extends AbstractHandler {/*** 每个责任节点都要说明下自己能处理哪些需求*/public DevelopmentEngineer() {super(AbstractHandler.DEVELOPER_LEVEL_REQUEST);}@Overrideprotected void response(IProject project) {System.out.println("项目组向开发人员咨询");System.out.println(project.getRequest());System.out.println("开发人员的答复是:找我就对了");}
}/*** @author Evad.Wu* @Description 产品经理* @date 2023-07-10*/
public class ProductManager extends AbstractHandler {/*** 每个责任节点都要说明下自己能处理哪些需求*/public ProductManager() {super(AbstractHandler.PRODUCT_MANAGER_LEVEL_REQUEST);}@Overrideprotected void response(IProject project) {System.out.println("项目组向产品经理咨询");System.out.println(project.getRequest());System.out.println("产品经理的答复是:找我就对了");}
}
项目组抽象、实现类
public interface IProject {/*** 获取咨询问题的类型** @return 类型编号*/int getType();/*** 获取咨询的内容** @return 咨询的内容*/String getRequest();
}public class ProjectImpl implements IProject {/*** 问题类型* 1-测试处理 2-开发处理 3-产品处理*/private final int type;/*** 本次处理的请求*/private String request;public ProjectImpl(int type, String request) {this.type = type;this.request = request;switch (this.type) {case 1 -> this.request += "测试方面的咨询";case 2 -> this.request += "开发方面的咨询";case 3 -> this.request += "产品方面的咨询";default -> this.request += "没有人对应的人员可以处理";}}/*** 获取咨询问题的类型** @return 类型编号*/public int getType() {return type;}/*** 获取咨询的内容** @return 咨询的内容*/public String getRequest() {return request;}
}
责任链
负责将节点串联起来
public class Chain<T extends AbstractHandler> {// 定义三个咨询对象private AbstractHandler peek;public Chain(Queue<T> sequence) {if (!sequence.isEmpty()) {T peek = sequence.peek();this.peek = peek;sequence.poll();for (T current : sequence) {peek.setNext(current);peek = current;}}}public AbstractHandler build() {return peek;}
}
入口类
public class ResponsibilityChainMain {public static void main(String[] args) {List<IProject> projectList = new ArrayList<>();projectList.add(new ProjectImpl(1, "项目出问题,需要人员支持..."));projectList.add(new ProjectImpl(2, "项目出问题,需要人员支持..."));projectList.add(new ProjectImpl(3, "项目出问题,需要人员支持..."));projectList.add(new ProjectImpl(4, "项目出问题,需要人员支持..."));Queue<AbstractHandler> sequence = new LinkedList<>();// 咨询的顺序是:测试、开发、产品经理sequence.add(new TestEngineer());sequence.add(new DevelopmentEngineer());sequence.add(new ProductManager());AbstractHandler handler = new Chain<>(sequence).build();for (IProject project : projectList) {handler.handleMessage(project);System.out.println();}}
}
结果
参考书籍
秦小波《设计模式之禅》