设计模式之责任链模式
1.引子
我们经常会去银行取钱,如果金额达到一定的数量则需要提前预约,否则无法立马提现。
假设有这么一个流程,提现金额小于等于10万则可以直接在柜台提取;提现金额大于10万小于等于20万则需要事先跟银行的客户经理预约然后才可以提取;提现金额大于20万的则需要事先预约并经银行经理授权后才能提取。这个例子就包含着责任链模式。
抽象出来就是:金额小于等于10万则直接在柜员处提取;否则如果金额小于等于20万则需要跟客户经理预约后提取;否则金额大于20万则需要预约后并经过银行经理授权后才能提取。很明显,根据金额的数量,提取过程需要先经过柜员,如果柜员没有权利则需要委托给客户经理,如果客户经理没有权利则委托给银行经理。这种委托的链路就是责任链模式。
抽象提取方法类:
public abstract class AbstractHandler {
// 自己没权利,则委托给上面的人
protected AbstractHandler successor = null;
public AbstractHandler getSuccessor() {
return successor;
}
public void setSuccessor(AbstractHandler successor) {
this.successor = successor;
}
// 处理提取过程
public abstract void handler(int number);
}
柜员处理金额小于等于10万的提取:
public class HandlerOne extends AbstractHandler {
@Override
public void handler(int number) {
if (number <= 10 ) {
System.out.println("您好,您取款金额为" + number + ", 请输入密码后可直接取走!");
} else {
System.out.println("您好,您取款金额为" + number + ",请与客户经理预约后取款!");
if (getSuccessor() != null) {
getSuccessor().handler(number);
}else {
System.out.println("您好,您取款金额为" + number + ",您无预约,无法取款!");
}
}
}
}
客户经理处理金额在10万-20万之间的提取:
public class HandlerTwo extends AbstractHandler {
@Override
public void handler(int number) {
if (number > 10 && number <= 20) {
System.out.println("您好,您取款金额为" + number + ",预约成功, 请输入密码后可直接取走!");
} else {
System.out.println("您好,您取款金额为" + number + ", 金额过大,还需要银行经理授权!");
if (getSuccessor() != null) {
getSuccessor().handler(number);
} else {
System.out.println("您好,您取款金额为" + number + ", 没有获得银行经理的授权,无法取款!");
}
}
}
}
银行经理处理金额大于20万的提取:
public class HandlerThree extends AbstractHandler {
@Override
public void handler(int number) {
System.out.println("您好,您取款金额为" + number + ", 您以获得银行经理授权,请输入密码后可直接取走!");
}
}
测试类:
public class Main {
public static void main(String[] args) {
HandlerOne handlerOne = new HandlerOne();
HandlerTwo handlerTwo = new HandlerTwo();
HandlerThree handlerThree = new HandlerThree();
handlerOne.setSuccessor(handlerTwo);
handlerTwo.setSuccessor(handlerThree);
handlerOne.handler(5);
System.out.println("==========================");
handlerOne.handler(16);
System.out.println("==========================");
handlerOne.handler(30);
}
}
运行结果:
您好,您取款金额为5, 请输入密码后可直接取走!
==========================
您好,您取款金额为16,请与客户经理预约后取款!
您好,您取款金额为16,预约成功, 请输入密码后可直接取走!
==========================
您好,您取款金额为30,请与客户经理预约后取款!
您好,您取款金额为30, 金额过大,还需要银行经理授权!
您好,您取款金额为30, 您已获得银行经理授权,请输入密码后可直接取走!
这种操作一步一步向上提交的过程,就是一种责任链模式。
2.责任链模式原理
《大话设计模式》中这样定义责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
上面的例子中,发送者和接受者都是继承同一个父类,父类中通过抽象类的注入解除了发送者和接受者的耦合关系;这种从柜员到客户经理到银行经理形成一条处理链,在这条链路上传递着提取的任务(handler方法);在这条链路上总会有一个对象会处理这个任务。
3.责任链模式使用场景
责任链模式感觉与类的加载机制有点相似,都是首先判断自己是否能够处理请求,不能处理则委托给后继者…,后面总会有一个对象会处理请求。责任链模式则把链中的对象完全解耦,提高链的可扩展性。所以有此类似的场景都可用责任链模式。
4.责任链模式特点
链中对象无需知道其他对象的实现方式,甚至不知道自己处于一个链中,这很好的把自己与其他对象进行解耦;
链的结构在测试类中定义,可随时增加或者修改链的结构,增强了给对象指派职责的灵活性;
5.参考资料
《大话设计模式》
https://blog.csdn.net/jason0539/article/details/45091639