先看经典职责链代码,
(代码来自维基)
package pattern;
import java.io.*;
abstract class PurchasePower {
protected final double base = 500;
protected PurchasePower successor;
public void setSuccessor(PurchasePower successor) {
this.successor = successor;
}
abstract public void processRequest(PurchaseRequest request);
}
class ManagerPPower extends PurchasePower {
private final double ALLOWABLE = 10 * base;
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < ALLOWABLE)
System.out.println("Manager will approve $" + request.getAmount());
else if (successor != null)
successor.processRequest(request);
}
}
class DirectorPPower extends PurchasePower {
private final double ALLOWABLE = 20 * base;
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < ALLOWABLE)
System.out.println("Director will approve $" + request.getAmount());
else if (successor != null)
successor.processRequest(request);
}
}
class VicePresidentPPower extends PurchasePower {
private final double ALLOWABLE = 40 * base;
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < ALLOWABLE)
System.out.println("Vice President will approve $"
+ request.getAmount());
else if (successor != null)
successor.processRequest(request);
}
}
class PresidentPPower extends PurchasePower {
private final double ALLOWABLE = 60 * base;
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < ALLOWABLE)
System.out
.println("President will approve $" + request.getAmount());
else
System.out.println("Your request for $" + request.getAmount()
+ " needs a board meeting!");
}
}
class PurchaseRequest {
private int number;
private double amount;
private String purpose;
public PurchaseRequest(int number, double amount, String purpose) {
this.number = number;
this.amount = amount;
this.purpose = purpose;
}
public double getAmount() {
return amount;
}
public void setAmount(double amt) {
amount = amt;
}
public String getPurpose() {
return purpose;
}
public void setPurpose(String reason) {
purpose = reason;
}
public int getNumber() {
return number;
}
public void setNumber(int num) {
number = num;
}
}
public class CheckAuthority {
public static void main(String[] args) {
ManagerPPower manager = new ManagerPPower();
DirectorPPower director = new DirectorPPower();
VicePresidentPPower vp = new VicePresidentPPower();
PresidentPPower president = new PresidentPPower();
manager.setSuccessor(director);
director.setSuccessor(vp);
vp.setSuccessor(president);
// enter ctrl+c to kill.
try {
while (true) {
System.out
.println("Enter the amount to check who should approve your expenditure.");
System.out.print(">");
double d = Double.parseDouble(new BufferedReader(
new InputStreamReader(System.in)).readLine());
manager.processRequest(new PurchaseRequest(0, d, "General"));
}
} catch (Exception e) {
System.exit(1);
}
}
}
这段代码实现了不同审批限额由不同级别的人去审批的功能。
该模式有如下特点:
1. 几个对象组成链表结构,用来向后传递请求;
2. 请求被处理,则返回;否则继续向后传递;(有的实现则是不论请求是否被处理,都向后传递)。
3. 对象都继承自同一个父类或实现了共同的用来处理请求的接口。
优点:
1. 发起者(调用者)与接收者分离。
2. 可动态插入职责链。
缺点:
1. 遍历链表有性能损耗。
职责链模式的经典应用是Servlet中的的Filter技术。略过Filter的很简单的使用
方法,我们来看看它在tomcat中的实现。为了说明方便,这里只是它的实现的一
个简化演示代码。
用户自定义的filter都需实现了如下的Filter接口,
doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws java.io.IOException,ServletException
用户在这个接口里写的代码可以截获请求。对截获的请求处理后,可以把处理权
传递给下一个filter。传递给下一个filter的方法是调用如下一行代码,
chain.doFilter(request,response);
这行代码是Servlet里的Filter技术的核心,所以接下来我们主要就是分析、模拟
这行代码做了什么,它是如何把请求传递给下一个filter的,下一个filter是何
时被创建的。
下面是对整个过程的简单模拟。很简单,就是读配置文件,生成多个
ApplicationFilterConfig对象(称呼它为配置对象),该配置对象负责生成
filter对象。
final class ApplicationFilterChain implements FilterChain {
private List filterConfigs = new ArrayList();
private Iterator iterator = null;
public void doFilter(ServletRequest request, ServletResponse response) {
if (this.iterator == null)
this.iterator = filters.iterator();
if (this.iterator.hasNext()) {
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) iterator
.next();// 在这里取得下一个filter的配置对象
Filter filter = filterConfig.getFilter();// 注意:在这里取得了下一个filter,这个filter就是你实现了filter接口的filter.
filter.doFilter(request, response, this);// 把请求传递个下一个filter处理
}
}
public void startFilter() {
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) iterator
.next();
Filter filter = filterConfig.getFilter();
filter.doFilter(request, response, this);
}
public void addFilterConfig(ApplicationFilterConfig filterConfig) {
filterConfigs.add(filterConfig);
}
}
final class ApplicationFilterConfig implements FilterConfig {
private Filter filter = null;
private String filterClass;
public Filter getFilter() {
if (this.filter != null)
return (this.filter);
Class clazz = classLoader.loadClass(filterClass);
this.filter = (Filter) clazz.newInstance();
return this.filter;
}
}
public class MainTest {
public FilterChain create() {
ApplicationFilterChain a = new ApplicationFilterChain();
List filters = readConfigFile();// 读取配置文件,获取filter信息,实现过程略
for (int i = 0; i < filters.size(); i++) {
ApplicationFilterConfig afc = (ApplicationFilterConfig) filters
.get(i);
a.addFilterConfig(afc);
}
return a;
}
public static void main(String args[]) {
(new MainTest()).create().startFilter();
}
}
tomcat的chain实现有3个要点,
1. 不是一下子全部初始化所有的filter对象,而是只初始化所有的配置对象。配
置对象的生成比filter对象的生成节省资源,生成配置对象只是存储了一些配置
信息。filter对象的生成需要反射,相对消耗资源。
2. 在第一次调用filter的时候,由配置对象生成filter对象。下一次再次调用则
直接使用已经生成的filter对象。缓存思路。
3. 由FilterChain维护一个链表,链表中存放着配置对象的链条,每次用户调用
一次chain.doFilter(req, res),链表就去取下一个配置对象,再通过配置对象
得到下一个filter,然后调用该filter,接着你在filter里写的逻辑就被执行了。
分享到:
相关推荐
C#面向对象设计模式 Chain of Responsibility 职责链模式 视频讲座下载
C#面向对象设计模式纵横谈(20):(行为型模式) Chain Of Responsibility 职责链模式
设计模式C++学习之责任链模式(Chain of Responsibility)
C#面向对象设计模式纵横谈(20):(行为型模式) Chain Of Responsibility 职责链模式
chain of responsibility 职责链模式(行为模式)来自于Microsoft官方网站视频教程,详细介绍了职责链模式的运用,且在本人提供的资源里可以下载到相关的PDF辅助文档帮助
23种设计模式之二十一(行为模式)Chain of Responsibility模式
C#面向对象设计模式纵横谈(14):Chain of Responsibility 职责链模式(行为型模式) (Level 300)
C#面向对象设计模式纵横谈(14):Chain of Responsibility 职责链模式(行为型模式)
职责链模式 设计模式 Chain of Responsibility 若有问题望指出。
【Java设计模式】(3)责任链Chain of Responsibility源码
责任链模式(Chain of Responsibility Pattern)是一种常见的行为模式。 使多个对象都有处理请求的机会,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象串成一条链,并沿着这条链一直传递该请求,直到有...
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 职责链模式的一个...
NULL 博文链接:https://stelin.iteye.com/blog/932101
NULL 博文链接:https://linkcqu.iteye.com/blog/355806
职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免发送者和接收者的耦合关系。将对象连成链并沿着这条链传递请求直到被处理 下面是一个设计模式的demo: #!/usr/bin/env python # -*- ...
Chain Of Responsibility.rar
主要介绍了Java设计模式之责任链模式(Chain of Responsibility模式)介绍,本文讲解了如何使用责任链模式,并给出了4种使用实例,需要的朋友可以参考下
chain-of-responsibility-demo 责任链模式demo
NULL 博文链接:https://gary0416.iteye.com/blog/913457