模式的秘密——责任链模式
一、什么是责任链模式
将接收者对象连成一条链条,并在该链上传递请求,直到有一个接收者对象处理它。通过让更多对象有机会处理请求,避免了请求发送者和接收者之间的耦合。
二、如何实现责任链模式
比如我们去奔驰4S店买车,一般4S店都会有销售人员、经理、总监、老板这样的层级。消费者肯定希望买车能给予一定的折扣,比如5%、20%甚至50%等,消费者提出不同比例的折扣,销售员不一定能直接同意,这时候就需要向经理请示,或许这个折扣经理也不能同意,经理有需要向总监请示,这个过程就是责任链传递的一个很好的例子,接下来,我们就来从源码的角度来学习什么是责任链。
1、首先我们需要定义一个处理折扣的抽象类作为接口
/*
* 价格处理人,负责处理客户折扣申请
*/
public abstract class PriceHandler {
/*
* 直接后继,用于传递请求
*/
protected PriceHandler successor;
public voidsetSuccessor(PriceHandler successor) {
this.successor = successor;
}
public abstract void processDiscount(float discount);
}
2、然后,我们需要编写销售人员、经理、总监和老板的操作类
/*
* 销售人员,可以批准<=5%的折扣
*/
public class SalesMan extends PriceHandler {
@Override
public void processDiscount(float discount) {
// TODO Auto-generated method stub
if(discount<=0.05){
System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
}else{
successor.processDiscount(discount);
}
}
}
/*
* 老板,可以批准50%以内的折扣
* 折扣超出50%,就拒绝申请
*/
public class Boss extends PriceHandler {
@Override
public void processDiscount(float discount) {
// TODO Auto-generated method stub
if(discount<=0.50){
System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
}else{
System.out.format("%s拒绝了折扣:%.2f%n", this.getClass().getName(), discount);
}
}
}
我们只列出销售人员和老板的源码,经理和总监的源码实现与销售人员类似,我们就不在赘述
3、为了降低程序的耦合度,我们需要创建一个PriceHandler的创建工厂
public classPriceHandlerFactory {
/*
* 创建PriceHandler的工厂方法
*/
public staticPriceHandler createPriceHandler() {
// TODO Auto-generated method stub
PriceHandlersales = new SalesMan();
PriceHandlerman = new Manager();
PriceHandlerdir = new Director();
PriceHandlerboss = new Boss();
sales.setSuccessor(man);
man.setSuccessor(dir);
dir.setSuccessor(boss);
return sales;
}
}
4、通过循环产生随机数,我们来模拟实现不同的折扣请求
/*
* 客户,请求折扣
*/
public class Customer {
private PriceHandler priceHandler;
public voidsetPriceHandler(PriceHandler priceHandler) {
this.priceHandler = priceHandler;
}
public void requestDiscount(float discount) {
priceHandler.processDiscount(discount);
}
public static void main(String[] args) {
Customercustomer = new Customer();
customer.setPriceHandler(PriceHandlerFactory.createPriceHandler());
Randomrand = new Random();
for (int i = 1; i <= 20; i++) {
System.out.print(i + "");
customer.requestDiscount(rand.nextFloat());
}
}
}
三、责任链模式灵活在哪儿
1、改变内部的传递规则
在上面的例子中,如果经理不在可以直接找总监。每个人都可以动态地指定他的继任者。
2、可以从责任链任何一关开始
如果经理不在,可以直接去找总监,责任链还会继续,不会受影响。
3、用于不用的区别
不用职责链的结构,我们需要和公司中的每一个层级都发生耦合关系。如果反映在代码上即使我们需要在一个类中去写上很多丑陋的if….else语句。如果用了职责链,相当于我们面对的是一个黑箱,我们只需要认识其中的一个部门,然后让黑箱内部去负责传递就好了
四、责任链模式的纯与不纯
一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。
纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。