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

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

时间: 2024-10-13 06:44:58

设计模式学习-责任链模式的相关文章

设计模式之责任链模式20170717

行为型设计模式之责任链模式: 一.含义 责任链模式的核心在"链"上,"链"是由多个处理者(对象)组成的,由这条链传递请求,直到有对象处理它为止(在链中决定谁来处理这个请求),并返回相应的结果 二.代码说明 1.主要有两个角色 1)处理者 它能够对请求做出处理(请求得到处理则直接返回,否则传到下一个处理者),设置下一个处理者(这两个操作可以抽象出来), 同时每个处理者都有一个相应的处理级别,以及具体的处理操作(父类实现请求传递,子类实现请求处理) 2)被处理者(请求者

C#设计模式:责任链模式

设计模式是面向对象编程的基础,是用于指导程序设计.在实际项目开发过程中,并不是一味将设计模式进行套用,也不是功能设计时大量引入设计模式.应该根据具体需求和要求应用适合的设计模式.设计模式是一个老话题了,因为最近在设计“网关API”组件(后续介绍),采用“责任链设计模式”进行设计,所以先进行回顾记录.  一.责任链模式介绍 责任链模式是指一个处理需要涉及多个过程或者角色参与处理,并基于某个约定组成一个链,每个过程或者角色拥有各自职责进行处理.责任链模式有效组织一个过程处理,同时子过程之间职责明确.

入门设计模式之责任链模式

学习更多设计模式请参考:入门设计模式之汇总篇 责任链模式:很多对象由每一个对象对其下家的引用而连接起来行成的一条链. 其实责任链模式一直在我们的身边.某一天,董事长有个想法,他吩咐给了经理,经理吩咐给了组长,组长分配给了你我.这时候我们发现,我们没有下级了呀,咋办,那就干呗. 上方这个任务分配的过程就是责任链模式,一个事件会一直向下层传递,董事长并不关心是谁解决的这个问题,对他来说只要问题解决了就行. Handle:抽象处理者,可理解为抽象的员工(经理组长普通程序员等都是继承了员工) Handl

Java进阶篇设计模式之八 ----- 责任链模式和命令模式

前言 在上一篇中我们学习了结构型模式的享元模式和代理模式.本篇则来学习下行为型模式的两个模式, 责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern). 责任链模式 简介 责任链模式顾名思义,就是为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行为型模式.在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接

Java设计模式之八 ----- 责任链模式和命令模式

前言 在上一篇中我们学习了结构型模式的享元模式和代理模式.本篇则来学习下行为型模式的两个模式, 责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern). 责任链模式 简介 责任链模式顾名思义,就是为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行为型模式.在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接

设计模式之责任链模式--- Pattern chain-of-responsibility

模式的定义 责任链模式定义如下: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it. 使多个对象都有机会处理请求,从而避免请求的发送

设计模式_责任链模式

定义 Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求.从而避免了请求的发送者和接受者之间的耦合关系.

Java设计模式之责任链模式、职责链模式

本文继续介绍23种设计模式系列之职责链模式. 什么是链 1.链是一系列节点的集合. 2..链的各节点可灵活拆分再重组. 职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止. 角色 抽象处理者角色(Handler):定义出一个处理请求的接口.如果需要,接口可以定义 出一个方法以设定和返回对下家的引用.这个角色通常由一个Java抽象类或者Java接口实现. 具体处理者角色(ConcreteHan

【GOF23设计模式】责任链模式

来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_责任链模式.公文审批.供应链系统的采购审批.异常链.过滤器和拦截器调用过程 1 package com.test.chainOfResp; 2 /** 3 * 封装请假的基本信息 4 */ 5 public class LeaveRequest { 6 private String empName; 7 private int leaveDays; 8 private String reason; 9 10 publi

Head First设计模式之责任链模式

一.定义 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止. 主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了. 何时使用:在处理消息的时候以过滤很多道. 如何解决:拦截的类都实现统一接口. 二.结构 从责任链模式的定义可以发现,责任链模式涉及的对象只有处理者角色,但由于有多个处理者,它们具有共同的处理请求的