之前忘记记录了,策略模式和状态模式是行为型模式。设计模式共23种,分三大类:
1).创建型模式 5 种:单例模式,建造者模式,原型模式,工厂方法模式,抽象工厂模式。
2).行为型模式 11 种:策略模式,状态模式,责任链模式,解释器模式,命令模式,观察者模式,备忘录模式,迭代器模式,模版方法模式,访问者模式,中介者模式。
3).结构型模式 7 种:代理模式,组合模式,适配器模式,装饰模式,享元模式,外观模式,桥接模式。
责任链模式是行为型模式之一,链就是一个节点一个节点首尾相连起来的模型,将每个节点看成一个对象,每个对象都有不同的处理逻辑,然后从链的首端开始发出请求,顺着这条链依次传递给每一个对象,直到有对象处理这个请求为止。是不是觉得这样的模式很熟悉?没错,常被面试到的事件传递机制就是采用的责任链模式。关于事件传递机制,我也有一篇博客有所记录。
第九章 使编程更有灵活性——责任链模式
1.定义
使多个对象都有机会处理请求,从而降低了请求的发送者和接收者之间的耦合,将这些对象连成一条链,顺着这条链依次传递请求,直到有对象处理该请求位为止。
2.使用场景
1).多个对象可以处理同一请求,但具体由哪个对象处理,则需要动态决定时。
2).在请求者不明确的情况下需要向多个对象中的一个提交请求时。
3).需要动态的指定一组对象处理请求时。
3.简单实现
以找领导报销为例,当你需要报销时,需要找上级领导申请,组长能批复的额度为1000元,当超过1000时,他也得去找上级领导申请,经理能批复的额度是5000元,如果超过了5000,他也得再找上级领导,依此类推,直到有领导处理这个请求为止。
定义一个Leader抽象类:
public abstract class Leader {
//上级领导,即当前级别处理不了时的下一个处理者
private Leader nextHandler;
public void setNextHandler(Leader leader) {
nextHandler = leader;
}
//当前级别能处理的程度
public abstract int limit();
//当前级别能处理时,即调用该方法具体处理请求
public abstract void handle(int money);
//处理请求时调用该方法,能处理,则调用handle()方法处理,不能处理则交给下一个处理者
public final void handleRequest(int money) {
if (money < limit()) {
handle(money);
} else {
nextHandler.handleRequest(money);
}
}
}
组长:
public class GroupLeader extends Leader {
@Override
public int limit() {
return 1000;
}
@Override
public void handle(int money) {
System.out.println("GroupLeader:" + money);
}
}
public class DirectorLeader extends Leader {
@Override
public int limit() {
return 5000;
}
@Override
public void handle(int money) {
System.out.println("DirectorLeader:" + money);
}
}
经理:
public class ManagerLeader extends Leader {
@Override
public int limit() {
return 10000;
}
@Override
public void handle(int money) {
System.out.println("ManagerLeader:" + money);
}
}
public class BossLeader extends Leader {
@Override
public int limit() {
return Integer.MAX_VALUE;
}
@Override
public void handle(int money) {
System.out.println("BossLeader:" + money);
}
}
在客户端如何调用:
GroupLeader mGroupLeader = new GroupLeader();
DirectorLeader mDirectorLeader = new DirectorLeader();
ManagerLeader mManagerLeader = new ManagerLeader();
BossLeader mBossLeader = new BossLeader();
mGroupLeader.setNextHandler(mDirectorLeader);
mDirectorLeader.setNextHandler(mManagerLeader);
mManagerLeader.setNextHandler(mBossLeader);
mGroupLeader.handleRequest(512);
mGroupLeader.handleRequest(1024);
mGroupLeader.handleRequest(9527);
mGroupLeader.handleRequest(10086);
可以看到打印:
可以看到,传入一个额度,找到了对应级别的处理者处理事件,其实责任链模式的优点不止体现在这里。
试想想,当我们报销的时候,是不管金额大小就只找你的组长报呢,还是根据金额大小去找对应级别的领导呢,肯定是前者,大领导才没工夫搭理我们这些虾兵蟹将呢。所以当我们需要报销一个非常大的额度时,我们肯定还是只找我们的组长报销,至于是怎么报下来的,组长是否又去找了上级领导,我们根本不知道,反正最终结果是报了就行了。
mGroupLeader.handleRequest(168888);
// mGroupLeader.handleRequest(1024);
// mGroupLeader.handleRequest(9527);
// mGroupLeader.handleRequest(10086);
可以看到我们是找组长报销的,但是最终给报销的是老板,调用者却没有直接和老板发生关系,这就降低了耦合度。
4.总结
之前虽然了解了事件分发机制,但是没想到其中还含有这么高深的模式。
优点:
1).可以对请求者和处理者进行解耦,提高代码灵活性。
缺点:
1).需要对链中的请求处理这进行遍历,如果遍历太多必然会影响性能,特别是一些递归调用中,所以需慎重。