没有demo的设计模式博客没有灵魂:https://gitee.com/gudaichaoren/pipeline-valve
最近开发个项目,刚好需要用到责任链设计模式,就重温了tomcat中pipeline-value责任链源码,刚好在这里记下笔记。
先来考考大家,怎么用代码完成以下需求?
工厂安装一台汽车,需要经过一套完整操作流水线,安装引擎 -> 安装窗子 -> 喷漆 ->质量检查, 当所有的流程依次走完这台汽车才安装成功。
大家应该很快想到使用责任链设计模式,下面我来说说tomcat中pipeline-valve责任链
pipeline的流程图
其中pipeline是一条管道,valve是一个一个的阀门,baisc是最后一个阀门,水流从第一个阀门进入,依次流过每个阀门,然后再依次返回。
下面直接上代码
先定义一个pipeline接口
public interface Pipeline {
void setBasic(Valve basic);
void addValve(Valve valve);
/**
* pipeline程序的启动方法
* @param isPass
*/
void invoke(boolean isPass);
}
创建一个安装汽车的pipeline管道
/**
* 安装汽车责任链
*/
public class InstallCarPipeline implements Pipeline {
/**
* 第一个阀门
*/
protected Valve first = null;
/**
* 最后一个阀门
*/
protected Valve basic = null;
@Override
public void setBasic(Valve valve) {
Valve oldBasic = this.basic;
// Update the pipeline
Valve current = first;
while (current != null) {
if (current.getNext() == oldBasic) {
current.setNext(valve);
break;
}
current = current.getNext();
}
this.basic = valve;
}
public Valve getFirst() {
if (first != null) {
return first;
}
return basic;
}
@Override
public void addValve(Valve valve) {
if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first;
while (current != null) {
if (current.getNext() == basic) {
current.setNext(valve);
valve.setNext(basic);
break;
}
current = current.getNext();
}
}
}
@Override
public void invoke(boolean isPass) {
//获取第一个阀门
Valve valve = getFirst();
if (valve!=null) {
valve.invoke(isPass);
return;
}
throw new RuntimeException("责任链上没有链阀门");
}
}
定义一个valve接口
public interface Valve {
/**
* 阀门内的执行的方法
* @param isPass
*/
void invoke(boolean isPass);
void setNext(Valve valve);
Valve getNext();
}
因为会有很多管道,我们将一些通用的变量方法放入 基础阀门 中
public abstract class BaseValve implements Valve {
/**
* 下一个阀门
*/
protected Valve next = null;
@Override
public void setNext(Valve valve) {
this.next = valve;
}
@Override
public Valve getNext() {
return next;
}
}
具体阀门类
/**
* 安装引擎阀门
*/
public class InstallEngineValve extends BaseValve {
@Override
public void invoke(boolean isPass) {
System.out.println("引擎安装完成");
this.next.invoke(true);
System.out.println("引擎安装交付");
}
}
/**
* 安装窗子阀门
*/
public class InstallWindowsValve extends BaseValve {
@Override
public void invoke(boolean isPass) {
System.out.println("窗子安装完成");
this.next.invoke(true);
System.out.println("窗子安装交付");
}
}
/**
* 喷漆阀门
*/
public class SprayPaintValve extends BaseValve {
@Override
public void invoke(boolean isPass) {
System.out.println("喷漆完成");
this.next.invoke(true);
System.out.println("喷漆交付");
}
}
/**
* 质检阀门,为最后一个阀门(basic)
*/
public class QualityInspectionValve extends BaseValve {
@Override
public void invoke(boolean isPass) {
System.out.println("\t\n质检合格通过\t\n");
}
}
最后来个测试类
public class test {
public static void main(String[] args) {
//创建pipeline管道
InstallCarPipeline installCarPipeline = new InstallCarPipeline();
//创建多个valve阀门
InstallEngineValve installEngineValve = new InstallEngineValve();
InstallWindowsValve installWindowsValve = new InstallWindowsValve();
SprayPaintValve sprayPaintValve = new SprayPaintValve();
QualityInspectionValve qualityInspectionValve = new QualityInspectionValve();
//阀门装入管道中
installCarPipeline.addValve(installEngineValve);
installCarPipeline.addValve(installWindowsValve);
installCarPipeline.addValve(sprayPaintValve);
installCarPipeline.setBasic(qualityInspectionValve);
//管道程序执行
installCarPipeline.invoke(true);
}
}
测试结果如下
引擎安装完成
窗子安装完成
喷漆完成
质检合格通过
喷漆交付
窗子安装交付
引擎安装交付
源码地址:https://gitee.com/gudaichaoren/pipeline-valve