今天来学习职责链模式,以下是官方定义:
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
我们暂且不必管它,熟悉J2EE的人都知道拦截器(Filter),这个filter就可以在一定程度上理解为职责链,所谓的链,就是当一条数据出现时,在这个链上的对象要处理一遍,如果可以处理,那么就截获处理,否则就交给链的下一个对象去处理。
举个例子来说,员工要请假,如果请假半天,跟项目经理说一声就ok了,但是请假一天的话,你和项目经理一说,项目经理说我处理不了,你找部门经理吧,于是你就找部门经理去请假,假如你要请假7天,这时候部门经理也处理不了了,你就要找总经理了。。。以此类推,这就是个典型的职责链模式。
说了这么多,我们还是看看具体代码是怎么实现的吧,我们用一个日常的小例子,就是孩子和爸爸妈妈爷爷要零花钱的例子,爷爷只能给50元以下的零花钱,妈妈能给50-100的零花钱,爸爸能给100以上的零花钱。就用这个例子,我们来看看代码实现
首先是处理零花钱的一个抽象类
package com.chainresponsibility.handler.abs;
/**
* 处理小孩要零花钱的抽象类
* @author ZHENGWEI
* @date 2015-8-11
*/
public abstract class Handler {
protected Handler nextHandler = null;
public Handler getNextHandler() {
return nextHandler;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 处理给孩子零花钱的具体方法
* @param childName
* @param money
*/
public abstract void moneyRequest(String childName, double money);
}
之后便是三个职责的具体实现了,中间包含必要的逻辑判断
package com.chainresponsibility.handler.concrete;
import com.chainresponsibility.handler.abs.Handler;
/**
* 爷爷处理零花钱的类,爷爷只能处理50元以内的零花钱
* @author ZHENGWEI
* @date 2015-8-11
*/
public class GrandFatherHandler extends Handler{
/**
* 爷爷只能处理50元以内的零花钱
*/
@Override
public void moneyRequest(String childName, double money) {
if(money <= 50){
//只管自己孙子的零花钱,别人的不管
if(childName.equals("小明")){
System.out.println("爷爷给了"+money+"元零花钱");
} else {
System.out.println("我不是你的爷爷,不能给你零花钱");
}
} else {
if(this.getNextHandler() != null){
System.out.println("你要的零花钱太多了,找你的妈妈去吧");
this.getNextHandler().moneyRequest(childName, money);
}
}
}
}
package com.chainresponsibility.handler.concrete;
import com.chainresponsibility.handler.abs.Handler;
/**
* 妈妈处理零花钱的类,妈妈只能处理100元以内的零花钱
* @author ZHENGWEI
* @date 2015-8-11
*/
public class MotherHandler extends Handler{
/**
* 妈妈只能处理100元以内的零花钱
*/
@Override
public void moneyRequest(String childName, double money) {
if(money > 50 && money <= 100){
//只管自己儿子的零花钱,别人的不管
if(childName.equals("小明")){
System.out.println("妈妈给了"+money+"元零花钱");
} else {
System.out.println("我不是你的妈妈,不能给你零花钱");
}
} else {
if(this.getNextHandler() != null){
System.out.println("你要的零花钱太多了,找你的爸爸去吧");
this.getNextHandler().moneyRequest(childName, money);
}
}
}
}
package com.chainresponsibility.handler.concrete;
import com.chainresponsibility.handler.abs.Handler;
/**
* 爸爸处理零花钱的类,爸爸能处理100元以上的零花钱
* @author ZHENGWEI
* @date 2015-8-11
*/
public class FatherHandler extends Handler{
/**
* 爸爸能处理100元以上的零花钱
*/
@Override
public void moneyRequest(String childName, double money) {
if(money > 100){
//只管自己儿子的零花钱,别人的不管
if(childName.equals("小明")){
System.out.println("爸爸给了"+money+"元零花钱");
} else {
System.out.println("我不是你的爸爸,不能给你零花钱");
}
}
}
}
最后是测试类
package com.chainresponsibility.main;
import com.chainresponsibility.handler.abs.Handler;
import com.chainresponsibility.handler.concrete.FatherHandler;
import com.chainresponsibility.handler.concrete.GrandFatherHandler;
import com.chainresponsibility.handler.concrete.MotherHandler;
public class ChainResponsibilityMain {
public static void main(String[] args) {
// 声明职责对象
Handler grandFatherHandler = new GrandFatherHandler();
Handler motherHandler = new MotherHandler();
Handler fatherHandler = new FatherHandler();
// 组装职责链
grandFatherHandler.setNextHandler(motherHandler);
motherHandler.setNextHandler(fatherHandler);
// 测试
grandFatherHandler.moneyRequest("小明", 30);
System.out.println("1==========");
grandFatherHandler.moneyRequest("小红", 30);
System.out.println("1==========");
grandFatherHandler.moneyRequest("小明", 70);
System.out.println("2==========");
grandFatherHandler.moneyRequest("小红", 70);
System.out.println("2==========");
grandFatherHandler.moneyRequest("小明", 130);
System.out.println("3==========");
grandFatherHandler.moneyRequest("小红", 130);
System.out.println("3==========");
}
}
我们来看看结果,防止大家看混了,我用线分开了
这就是一个简单的职责链模式,数据从链中一个一个的进行判断,直到遇见一个可以处理的为止。
在我的理解中,职责链模式对象的处理原则只有两个:
1、自己处理
2、自己不能处理,把责任推给下一个对象
如果不满足这个条件,不能说不是职责链模式,至少它不是一个真正的职责链模式。不过在真正的项目中,貌似真正的职责链模式还是比较少见的,因为有的时候不可能把所有的情况都预料到,这就需要我们自己进行取舍了。