设计模式学习-责任链模式

1.定义

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

2.类图

3.代码示例 

 

  1 package com.zhaoyangwoo.chainOfResponsibility;
  2 
  3 /**
  4  * Created by john on 16/6/16.
  5  * 职责链模式,经费审批场景
  6  */
  7 public class Responsibility {
  8 
  9     public static void main(String[] args) {
 10 
 11         //zhaoyanghoo报销100元
 12         Request request = new Request();
 13         request.setName("zhaoyanghoo");
 14         request.setLevel(new Level(100));
 15 
 16         ApprovalUtil.handleApproval(request).print();
 17 
 18         //zhaoyanghoo报销100元
 19         Request request2 = new Request();
 20         request2.setName("xiaohong");
 21         request2.setLevel(new Level(10000));
 22 
 23         ApprovalUtil.handleApproval(request2).print();
 24 
 25 
 26         //zhaoyanghoo报销100元
 27         Request request3 = new Request();
 28         request3.setName("xiaoming");
 29         request3.setLevel(new Level(10000000));
 30         ApprovalUtil.handleApproval(request3).print();
 31 
 32     }
 33 
 34 }
 35 
 36 /**
 37  * 用这个工具类封装内部关系,client只需要知道ApprovalUtil,而不需要跟manage/director等关联
 38  */
 39 class ApprovalUtil {
 40     static Approval manage, director, cfo;
 41 
 42     static {
 43         manage = new Manager();
 44         director = new Director();
 45         cfo = new CFO();
 46 
 47         manage.setSuccessor(director);
 48         director.setSuccessor(cfo);
 49     }
 50 
 51     static Response handleApproval(Request request) {
 52         return manage.handleApproval(request);
 53     }
 54 }
 55 
 56 
 57 /**
 58  * 抽象类,审批人
 59  */
 60 abstract class Approval {
 61 
 62     public void setSuccessor(Approval successor) {
 63         this.successor = successor;
 64     }
 65 
 66     protected abstract Level getLevel();
 67 
 68     //后继审批人
 69     protected Approval successor;
 70 
 71 
 72     public final Response handleApproval(Request request) {
 73         if (request == null || request.getLevel() == null) return null;
 74         if (this.getLevel() != null && this.getLevel().higherThen(request.getLevel())) {
 75             return this.hanlder(request);
 76         } else if (this.successor != null) {
 77             return this.successor.handleApproval(request);
 78         } else
 79             return new Response("无人能处理" + request.getName() + "的报销请求");
 80     }
 81 
 82     protected abstract Response hanlder(Request request);
 83 }
 84 
 85 /**
 86  * 经理只审批500元内经费
 87  */
 88 class Manager extends Approval {
 89 
 90     //最多审批500元
 91     private final static Level level = new Level(500);
 92 
 93     @Override
 94     protected Level getLevel() {
 95         return level;
 96     }
 97 
 98     @Override
 99     public Response hanlder(Request request) {
100         return new Response(String.format("经理审批了%s的%d元报销", request.getName(), request.getLevel().getAmount()));
101     }
102 }
103 
104 /**
105  * 总监审批1000元内的报销
106  */
107 class Director extends Approval {
108 
109     //最多审批1000元
110     private final static Level level = new Level(1000);
111 
112     @Override
113     protected Level getLevel() {
114         return level;
115     }
116 
117     @Override
118     public Response hanlder(Request request) {
119         return new Response(String.format("总监审批了%s的%d元报销", request.getName(), request.getLevel().getAmount()));
120     }
121 }
122 
123 /**
124  * CFO审批100000
125  */
126 class CFO extends Approval {
127 
128     //最多审批500元
129     private final static Level level = new Level(100000);
130 
131     @Override
132     protected Level getLevel() {
133         return level;
134     }
135 
136     @Override
137     public Response hanlder(Request request) {
138         return new Response(String.format("CFO审批了%s的%d元报销", request.getName(), request.getLevel().getAmount()));
139     }
140 }
141 
142 //请求模拟类
143 class Request {
144     public Level getLevel() {
145         return level;
146     }
147 
148     public void setLevel(Level level) {
149         this.level = level;
150     }
151 
152     //请求的级别
153     Level level;
154 
155     //姓名
156     String name;
157 
158     public String getName() {
159         return name;
160     }
161 
162     public void setName(String name) {
163         this.name = name;
164     }
165 }
166 
167 //请求级别类
168 class Level {
169 
170     public Level(int amount) {
171         this.amount = amount;
172     }
173 
174     public int getAmount() {
175         return amount;
176     }
177 
178     //报销金额
179     private final int amount;
180 
181     //如果高于当前金额,则无法处理
182     public boolean higherThen(Object obj) {
183         if (obj == null) return false;
184         if (obj == this) {
185             return true;
186         } else if (obj instanceof Level) {
187             return this.amount > ((Level) obj).amount;
188         }
189         return false;
190     }
191 }
192 
193 //相应模拟类
194 class Response {
195     public Response(String message) {
196         this.message = message;
197     }
198 
199     public String getMessage() {
200         return message;
201     }
202 
203     public void setMessage(String message) {
204         this.message = message;
205     }
206 
207     //审批结果
208     private String message;
209 
210     //打印审批结果
211     public void print() {
212         System.out.println(message);
213     }
214 }

 

4.应用场景举例

  • 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
  • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 可动态指定一组对象处理请求

5.JDK源码中的模式实现

  java.util.logging.Logger类应用了责任链模式

public void log(LogRecord record) {
        if (!isLoggable(record.getLevel())) {
            return;
        }
        Filter theFilter = filter;
        if (theFilter != null && !theFilter.isLoggable(record)) {
            return;
        }

        // Post the LogRecord to all our Handlers, and then to
        // our parents' handlers, all the way up the tree.

        Logger logger = this;
        while (logger != null) {
            final Handler[] loggerHandlers = isSystemLogger
                ? logger.accessCheckedHandlers()
                : logger.getHandlers();

            for (Handler handler : loggerHandlers) {
                handler.publish(record);
            }

            final boolean useParentHdls = isSystemLogger
                ? logger.useParentHandlers
                : logger.getUseParentHandlers();

            if (!useParentHdls) {
                break;
            }

            logger = isSystemLogger ? logger.parent : logger.getParent();
        }
    }



    public boolean isLoggable(Level level) {
        if (level.intValue() < levelValue || levelValue == offValue) {
            return false;
        }
        return true;
    } 

6.思考

  • 如何控制链的长度,以保证性能
   可以在抽象类中添加一个static final的常量,标志最长的链有MAX个元素,一个static的set类型变量,setSuccessor方法中将handler添加到set变量中,比较MAX和Set.size()。

 

7.参考

  1.《JAVA与模式》之责任链模式

  2.java.util.logging.Logger使用详解

 

posted @ 2016-06-18 23:02  jiudianban  阅读(277)  评论(0编辑  收藏  举报