java设计模式-职责链模式

模式导读:

     作为一名大学生,相信我们都有过请假的经历,在我们请假是总会碰到这样的场景,就是当请假的时间超过5天(包括5天),我们的请假条就不能由班主任进行审阅通过了,而是需要上交院系,由院领导进行审阅通过,当请假的时间超过一个月,就得由学校的教务处进行审阅通过。这便是在其位司其职,职责链模式也就相当于给了不同角色不同权限,权限低的不能去执行权限高的任务。

参考类图:

 

责任链模式涉及到的角色如下所示:

  ●  抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。

  ●  具体处理者(Department/Leader/HeadTeacher)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

代码实现:

1.首先要有一个抽象的处理者类,在其中要包含对具体处理者角色的引用,同时定义一个处理请求的抽象方法

 1 package com.etc;
 2 //定义一个抽象的处理者类
 3 public abstract class Handler {
 4     public Handler sucesser;
 5    
 6     //定义一个抽象的处理请求的方法
 7     public abstract String handlerRequest(String user,int days);
 8     
 9     //获取当前角色的下一个处理者角色
10     public Handler getNextHandler() {
11         return sucesser;
12     }
13     //设置当前角色的下一个处理者角色
14     public void setNextHandler(Handler sucesser) {
15         this.sucesser=sucesser;
16     }
17 
18 }

2.然后定义具体的处理者角色,根据不同情况加以判断处理情况

(1)HeadTeacher.java

 1 package com.etc;
 2 
 3 //班主任处理请假请求
 4 public class HeadTeacher extends Handler {
 5     @Override
 6     public String handlerRequest(String user, int days) {
 7         if (days < 5) {
 8             System.out.println("班主任同意" + user + "同学的请假请求");
 9         } else {
10             System.out.println("班主任无法处理" + user + "同学的请假请求");
11         }
12         // 如果下一个执行者不为空,由下一个执行者执行
13         if (getNextHandler() != null) {
14             return getNextHandler().handlerRequest(user, days);
15         }
16         return null;
17     }
18 
19 }

(2)Department.java

 1 package com.etc;
 2 
 3 //院系主任处理请假请求
 4 public class Department extends Handler {
 5 
 6     @Override
 7     public String handlerRequest(String user, int days) {
 8 
 9         if (days < 30) {
10             System.out.println("院系主任同意" + user + "同学的请假请求");
11         } else {
12             System.out.println("院系主任无法处理" + user + "同学的请假请求");
13         }
14         if (getNextHandler() != null) {
15             return getNextHandler().handlerRequest(user, days);
16         }
17         return null;
18     }
19 
20 }

(3)Leader.java

 1 package com.etc;
 2 
 3 //校级主任处理请假请求
 4 public class Leader extends Handler {
 5 
 6     @Override
 7     public String handlerRequest(String user, int days) {
 8         if (days >= 30) {
 9             System.out.println("校级主任同意" + user + "同学的请假请求");
10         } else if (getNextHandler() != null) {
11             return getNextHandler().handlerRequest(user, days);
12         }
13         return null;
14     }
15 
16 }

3.具体的客户端类

 1 package com.etc;
 2 
 3 public class Client {
 4 
 5     public static void main(String[] args) {
 6         // 获取三个不同的处理者对象
 7         Handler h1 = new HeadTeacher();
 8         Handler h2 = new Department();
 9         Handler h3 = new Leader();
10         
11         // 设置角色的处理层次
12         h2.setNextHandler(h3);
13 
14         h1.handlerRequest("李四", 5);
15         System.out.println("*************************");
16         h2.handlerRequest("王五", 15);
17         System.out.println("*************************");
18         h2.handlerRequest("朱七", 30);
19 
20     }
21 
22 }

运行效果截图:

职责链模式的优缺点:

优点:

(1) 职责链模式使得一个对象无须知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,接收者和发送者都没有对方的明确信息,且链中的对象不需要知道链的结构,由客户端负责链的创建,降低了系统的耦合度。

(2) 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。

(3) 在给对象分派职责时,职责链可以给我们更多的灵活性,可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的职责。

(4) 在系统中增加一个新的具体请求处理者时无须修改原有系统的代码,只需要在客户端重新建链即可,从这一点来看是符合“开闭原则”的。

缺点:

(1) 由于一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理。

(2) 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。

(3) 如果建链不当,可能会造成循环调用,将导致系统陷入死循环。

适用场景:

(1) 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。

(2) 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

(3) 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。

 

posted @ 2019-04-24 10:58  无影云  阅读(1167)  评论(0编辑  收藏  举报