设计模式之职责链模式。
在一个系统中,一个请求可以被多个对象所处理,职责链通过类似链表的方式将多个处理对象连接在一起,客户端沿着自定义的顺序传递请求。职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求
。
0x00 组成部分
Handler:抽象处理者,声明处理请求的方法,同时持有下一个处理者的引用
。
ConcreteHandler:具体处理者,通常有多个,实现了处理请求的方法,也可以选择性的处理部分请求
,再传递给下一个处理者继续处理。
Client:客户端负责创建具体的链。
架构UML图如下。
0x01 示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 package com.kkk.pattern.chain; * 官员接口,充当抽象请求处理者。 * Created by z3jjlzt on 2018/1/11. */ public abstract class Official { protected Official successor; public void setSuccessor (Official successor) { this .successor = successor; } public abstract void handleReq (int level) ; } * 县令,充当具体处理者。 * Created by z3jjlzt on 2018/1/11. */ public class Magistrate extends Official { @Override public void handleReq (int level) { if (level <= Lawsuit.LEVEL_1) { System.out.println("本县令又可以受贿了,好开心!!!" ); } else { System.out.println("这么大的案件,我可不敢自己管,感觉交给上司!!!" ); successor.handleReq(level); } } } * 总督,充当具体处理者。 * Created by z3jjlzt on 2018/1/11. */ public class Governor extends Official { @Override public void handleReq (int level) { if (level <= Lawsuit.LEVEL_2) { System.out.println("本总督好想处理大案件啊,可是却天天处理这些个破案件,真浪费了我的才华!!!" ); } else { System.out.println("好想自己处理啊,可是我没权利管,好可惜。。。" ); successor.handleReq(level); } } } * 丞相,充当具体处理者。 * Created by z3jjlzt on 2018/1/11. */ public class PrimeMinister extends Official { @Override public void handleReq (int level) { if (level <= Lawsuit.LEVEL_3) { System.out.println("本相今天判他个100年!!!" ); } else { System.out.println("泱泱大国可不能毁在我手里呀,感觉通知圣上!!!" ); successor.handleReq(level); } } } * 皇帝,充当具体处理者。 * Created by z3jjlzt on 2018/1/11. */ public class Emperor extends Official { private Random random = new Random(); private int mood; public int getMood () { mood = random.nextInt(3 ); return mood; } @Override public void handleReq (int level) { switch (getMood()) { case 0 : System.out.println("寡人今日心情欠佳,无心理会朝事" ); break ; case 1 : System.out.println("容我看看是谁吃了豹子胆,胆敢当卖国贼!!" ); break ; default : System.out.println("陛下在睡觉!!!" ); break ; } } } ** * 官司分类. * Created by z3jjlzt on 2018 /1 /11 . */ public class Lawsuit { public static final int LEVEL_1 = 1 ; public static final int LEVEL_2 = 2 ; public static final int LEVEL_3 = 3 ; public static final int LEVEL_4 = 4 ; } * 客户端,负责创建职责链。 * Created by z3jjlzt on 2018/1/11. */ public class Client { public static void main (String[] args) { Official o1,o2,o3,o4; o1 = new Magistrate(); o2 = new Governor(); o3 = new PrimeMinister(); o4 = new Emperor(); o1.setSuccessor(o2); o2.setSuccessor(o3); o3.setSuccessor(o4); o1.handleReq(1 ); System.out.println(); o4.handleReq(2 ); System.out.println(); o3.handleReq(3 ); System.out.println(); o1.handleReq(4 ); System.out.println(); o1.handleReq(4 ); System.out.println(); o1.handleReq(4 ); System.out.println(); o1.handleReq(4 ); } } 随机一个结果: 本县令又可以受贿了,好开心!!! 寡人今日心情欠佳,无心理会朝事 本相今天判他个100 年!!! 这么大的案件,我可不敢自己管,感觉交给上司!!! 好想自己处理啊,可是我没权利管,好可惜。。。 泱泱大国可不能毁在我手里呀,感觉通知圣上!!! 容我看看是谁吃了豹子胆,胆敢当卖国贼!! 这么大的案件,我可不敢自己管,感觉交给上司!!! 好想自己处理啊,可是我没权利管,好可惜。。。 泱泱大国可不能毁在我手里呀,感觉通知圣上!!! 寡人今日心情欠佳,无心理会朝事 这么大的案件,我可不敢自己管,感觉交给上司!!! 好想自己处理啊,可是我没权利管,好可惜。。。 泱泱大国可不能毁在我手里呀,感觉通知圣上!!! 陛下在睡觉!!! 这么大的案件,我可不敢自己管,感觉交给上司!!! 好想自己处理啊,可是我没权利管,好可惜。。。 泱泱大国可不能毁在我手里呀,感觉通知圣上!!! 寡人今日心情欠佳,无心理会朝事
0xff 总结
优点:无需知道请求具体由哪个处理者处理,新增处理者灵活,符合开闭原则。
缺点:请求不一定会被处理,如果客户端建立职责链不当,会造成死循环。
适用场景:请求的处理者在运行时才确定,在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。