设计模式-责任链模式

180 阅读6分钟

一、模式定义

为请求创建了一个接受者对象的链;因此责任链的数据结构是一个线性的数据结构,即链表或者数组;
优点:
1)请求的发送者与接收者解耦;
2)可以控制执行顺序;
3)符合开闭原则和单一职责原则;

二、案例说明

例如目前有个客户端的请求,在服务器端需要经过请求频率分析、登陆认证、访问权限、敏感词过滤等过程,那么这个时候我们就可以考虑使用责任链模式进行处理;

三、示例代码

  1 /**
  2  * 类描述:  责任链模式
  3  *
  4  * @author XXSD
  5  * @version 1.0.0
  6  * @date 2020/2/5 0005 上午 10:03
  7  */
  8 public class ResponsibilityTest {
  9     public static void main(String[] values) {
 10 
 11         final Request build = new Request.RequestBuilder().setTest1(true).setTest2(true).setTest3(true).build();
 12 
 13         final RequestTest1 requestTest1 = new RequestTest1(new RequestTest2(null));
 14         if (requestTest1.process(build)) {
 15             System.out.println("处理成功");
 16         }else{
 17             System.err.println("处理失败");
 18         }
 19     }
 20 }
 21 
 22 /**
 23  * 类描述: 请求数据内容
 24  * 用于描述请求的数据
 25  *
 26  * @author : XXSD
 27  * @date : 2020/2/5 0005 上午 10:06
 28  */
 29 class Request {
 30     private boolean test1;
 31     private boolean test2;
 32     private boolean test3;
 33     private String requestBody;
 34 
 35     /**
 36      * 功能描述:请求数据内容
 37      *
 38      * @author : XXSD
 39      * @date : 2020/2/5 0005 上午 10:08
 40      */
 41     public Request(boolean test1, boolean test2, boolean test3) {
 42         this.test1 = test1;
 43         this.test2 = test2;
 44         this.test3 = test3;
 45     }
 46 
 47     public boolean isTest1() {
 48         return test1;
 49     }
 50 
 51     public void setTest1(boolean test1) {
 52         this.test1 = test1;
 53     }
 54 
 55     public boolean isTest2() {
 56         return test2;
 57     }
 58 
 59     public void setTest2(boolean test2) {
 60         this.test2 = test2;
 61     }
 62 
 63     public boolean isTest3() {
 64         return test3;
 65     }
 66 
 67     public void setTest3(boolean test3) {
 68         this.test3 = test3;
 69     }
 70 
 71     /**
 72      * 类描述: 构造对象
 73      * 构造者模式
 74      *
 75      * @author : XXSD
 76      * @date : 2020/2/5 0005 上午 10:09
 77      */
 78     static class RequestBuilder {
 79         private boolean test1;
 80         private boolean test2;
 81         private boolean test3;
 82 
 83         public boolean isTest1() {
 84             return test1;
 85         }
 86 
 87         public RequestBuilder setTest1(boolean test1) {
 88             this.test1 = test1;
 89             return this;
 90         }
 91 
 92         public boolean isTest2() {
 93             return test2;
 94         }
 95 
 96         public RequestBuilder setTest2(boolean test2) {
 97             this.test2 = test2;
 98             return this;
 99         }
100 
101         public boolean isTest3() {
102             return test3;
103         }
104 
105         public RequestBuilder setTest3(boolean test3) {
106             this.test3 = test3;
107             return this;
108         }
109 
110         /**
111          * 功能描述:构造模式构造器
112          *
113          * @author : XXSD
114          * @date : 2020/2/5 0005 上午 10:12
115          */
116         public Request build() {
117             return new Request(test1, test2, test3);
118         }
119     }
120 }
121 
122 /**
123  * 类描述: 链描述抽象
124  * 这里我们使用单向链表实现
125  *
126  * @author : XXSD
127  * @date : 2020/2/5 0005 上午 10:13
128  */
129 abstract class Handler {
130     /**
131      * 属性描述:下级链对象
132      *
133      * @date : 2020/2/5 0005 上午 10:16
134      */
135     private Handler next;
136 
137     /**
138      * 功能描述:链描述抽象
139      *
140      * @author : XXSD
141      * @date : 2020/2/5 0005 上午 10:17
142      */
143     public Handler(Handler next) {
144         this.next = next;
145     }
146 
147     /**
148      * 功能描述:下级链对象
149      *
150      * @author : XXSD
151      * @date : 2020/2/5 0005 上午 10:20
152      */
153     public Handler getNext() {
154         return next;
155     }
156 
157     /**
158      * 功能描述:下级链对象
159      *
160      * @author : XXSD
161      * @date : 2020/2/5 0005 上午 10:20
162      */
163     public void setNext(Handler next) {
164         this.next = next;
165     }
166 
167     /**
168      * 功能描述:业务处理及返回
169      *
170      * @param request 需要处理的数据
171      * @return : 返回结果
172      * @author : XXSD
173      * @date : 2020/2/5 0005 上午 10:22
174      */
175     abstract boolean process(Request request);
176 }
177 
178 /**
179 * 类描述: 第一个节点
180 * @author : XXSD
181 * @date : 2020/2/5 0005 上午 10:25
182 */
183 class RequestTest1 extends Handler {
184 
185     /**
186      * 功能描述:链描述抽象
187      *
188      * @param next 下级节点
189      * @author : XXSD
190      * @date : 2020/2/5 0005 上午 10:17
191      */
192     public RequestTest1(Handler next) {
193         super(next);
194     }
195 
196     /**
197      * 功能描述:业务处理及返回
198      *
199      * @param request 需要处理的数据
200      * @return : 返回结果
201      * @author : XXSD
202      * @date : 2020/2/5 0005 上午 10:22
203      */
204     @Override
205     boolean process(Request request) {
206         System.out.println(this.getClass().getSimpleName() + "开始处理");
207         if(request.isTest1()){
208             final Handler next = getNext();
209             if (next==null){
210                 return request.isTest1();
211             }
212             if (!next.process(request)) {
213                 return false;
214             }else{
215                 return true;
216             }
217         }
218         return false;
219     }
220 }
221 
222 /**
223  * 类描述: 第一个节点
224  * @author : XXSD
225  * @date : 2020/2/5 0005 上午 10:25
226  */
227 class RequestTest2 extends Handler {
228 
229     /**
230      * 功能描述:链描述抽象
231      *
232      * @param next 下级节点
233      * @author : XXSD
234      * @date : 2020/2/5 0005 上午 10:17
235      */
236     public RequestTest2(Handler next) {
237         super(next);
238     }
239 
240     /**
241      * 功能描述:业务处理及返回
242      *
243      * @param request 需要处理的数据
244      * @return : 返回结果
245      * @author : XXSD
246      * @date : 2020/2/5 0005 上午 10:22
247      */
248     @Override
249     boolean process(Request request) {
250         System.out.println(this.getClass().getSimpleName() + "开始处理");
251         if(request.isTest2()){
252             final Handler next = getNext();
253             if (next==null){
254                 return request.isTest2();
255             }
256             if (!next.process(request)) {
257                 return false;
258             }else{
259                 return true;
260             }
261         }
262         return false;
263     }
264 }