前言
责任链模式:
流水线作业,流水线上的每个节点都能处理自己所承担职责的任务。(个人理解)
责任链的特点:
①:有一个链式的流水线(定义主干)
②:流水线上的每个处理任务的节点都拥有下一个处理任务的节点的引用(当前节点不能处理则调用下一个节点来处理)
③:调用者不用关心是哪个责任链处理的,只需关心当前任务是否处理成功(有点像黑盒的意思)
责任链生活中的场景:
们去食堂吃饭,食堂有三个不同价位的饭,食堂可以开三个窗口分别卖不同的饭,另一个方式就是一个窗口来处理,我们只需把我们想吃的饭告诉食堂阿姨,阿姨负责给我们打饭。
代码:
1 /** 2 * Created by sam on 2019/4/29. 3 * 定义主干 4 */ 5 public interface Filter { 6 7 /** 定义调用方法 */ 8 void doFilter(FilterChain filterChain); 9 10 }
1 /** 2 * Created by sam on 2019/4/29. 3 * A窗口 4 */ 5 public class AfilterChain extends FilterChain{ 6 7 public AfilterChain(FilterChain nextFilter) { 8 super(1, nextFilter); 9 } 10 11 @Override 12 public void doFilter(FilterChain filterChain) { 13 System.out.println("AfilterChain"); 14 if (filterChain.getNum().equals(1)){ 15 System.out.println("A饭!"); 16 } 17 super.doFilter(filterChain); 18 } 19 20 }
1 /** 2 * Created by sam on 2019/4/29. 3 * B窗口 4 */ 5 public class BfilterChain extends FilterChain{ 6 7 public BfilterChain(FilterChain nextFilter) { 8 super(2, nextFilter); 9 } 10 11 12 @Override 13 public void doFilter(FilterChain filterChain) { 14 System.out.println("BfilterChain"); 15 if (filterChain.getNum().equals(2)){ 16 System.out.println("B饭!"); 17 } 18 super.doFilter(filterChain); 19 } 20 21 }
1 /** 2 * Created by sam on 2019/4/29. 3 * c窗口 4 */ 5 public class CfilterChain extends FilterChain { 6 7 public CfilterChain(FilterChain nextFilter) { 8 super(3, nextFilter); 9 } 10 11 @Override 12 public void doFilter(FilterChain filterChain) { 13 System.out.println("CfilterChain"); 14 if (filterChain.getNum().equals(3)){ 15 System.out.println("C饭!"); 16 } 17 super.doFilter(filterChain); 18 } 19 }
1 /** 2 * Created by sam on 2019/4/29. 3 * 定义主干的具体逻辑 4 */ 5 public class FilterChain implements Filter { 6 7 8 /** 窗口的定义 */ 9 private Integer num; 10 11 /** 一个责任链的引用 */ 12 private FilterChain nextFilter; 13 14 15 public Integer getNum() { 16 return num; 17 } 18 19 public void setNum(Integer num) { 20 this.num = num; 21 } 22 23 public FilterChain getNextFilter() { 24 return nextFilter; 25 } 26 27 public void setNextFilter(FilterChain nextFilter) { 28 this.nextFilter = nextFilter; 29 } 30 31 public FilterChain(Integer num, FilterChain nextFilter) { 32 this.num = num; 33 this.nextFilter = nextFilter; 34 } 35 36 public FilterChain(FilterChain nextFilter) { 37 this.nextFilter = nextFilter; 38 } 39 40 41 42 @Override 43 public void doFilter(FilterChain filterChain) { 44 if (null == nextFilter || null == filterChain){ 45 System.out.println("责任链调用完毕!"); 46 return; 47 } 48 49 //调用下一个责任链处理 50 nextFilter.doFilter(filterChain); 51 } 52 53 54 }
测试用例:
1 /** 2 * Created by sam on 2019/4/29. 3 */ 4 public class FilterTest { 5 6 7 public static void main(String[] args) { 8 AfilterChain afilterChain = new AfilterChain(new CfilterChain(new BfilterChain(null))); 9 FilterChain filterChain = new FilterChain(1,afilterChain); 10 filterChain.doFilter(filterChain); 11 } 12 13 }
测试结果:
我们发现,责任链的上的每一个节点都有机会处理请求,只是根据节点的职责是选择当前节点处理还是交给下一个节点处理。上面的责任链还是有一点小瑕疵,难道我们每次调用责任链都要显式的创建一个责任链路吗?这样是不是很麻烦,其实这种事情我们可以交给spring的容器帮我们管理。
spring容器的责任链配置:
1 <bean id="cfilterChain" class="com.bju.otter.mainprogram.filter.CfilterChain" > 2 <constructor-arg name="nextFilter"> 3 <null/> 4 </constructor-arg> 5 </bean> 6 7 <bean id="bfilterChain" class="com.bju.otter.mainprogram.filter.BfilterChain" > 8 <constructor-arg ref="cfilterChain"/> 9 </bean> 10 11 <bean id="afilterChain" class="com.bju.otter.mainprogram.filter.AfilterChain" > 12 <constructor-arg ref="bfilterChain"/> 13 </bean> 14 15 <bean id="filterChain" class="com.bju.otter.mainprogram.filter.FilterChain"> 16 <constructor-arg ref="afilterChain"/> 17 </bean>
测试用例:
1 /** 2 * Created by sam on 2019/4/29. 3 */ 4 public class FilterTest extends BaseTest{ 5 6 7 @Resource(name = "filterChain") 8 private FilterChain filterChain; 9 10 @Test 11 public void testFilter(){ 12 filterChain.setNum(2); 13 filterChain.doFilter(filterChain); 14 } 15 16 17 18 }
测试结果:
总结:
如果在代码中有很多的if分支,我们可以考虑优化称责任链模式,调用者无需关系具体调用的那个方法,只需关心调用结果即可。
)