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


    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使用详解

    作者: zhaoyanghoo
    出处: http://www.cnblogs.com/zhaoyanghoo/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    POJ 1082 博弈推规律
    博弈论总结
    POJ 2502 Subway 关键在建图
    【算法设计与数据结构】为何程序员喜欢将INF设置为0x3f3f3f3f?
    一位ACMer过来人的心得
    POJ1724 Dij队列优化邻接表
    Dijkstra队列优化矩阵版
    Uva247 Floyd传递闭包+map处理
    简爬新浪新闻网
    爬href链接
  • 原文地址:https://www.cnblogs.com/zhaoyanghoo/p/5588595.html
Copyright © 2020-2023  润新知