2019独角兽企业重金招聘Python工程师标准>>>
一. 场景
相信我们都有过这样的经历;
我们去职能部门办理一个事情,先去了A部门,到了地方被告知这件事情由B部门处理;
当我们到了B部门的时候,又被告知这件事情已经移交给了C部门处理;
这时我们又顶着炎热的天气跑到了C部门,被告知这件事情并不是由C处理,要到D部门去... ...
这就是一个责任链模式,将多个部门组成一条责任链,然后按照在链上的顺序依次找到负责部门来处理问题;
二. 应用
我们假定有一个数字需要处理;
2.1 定义发生问题的类Trouble
/*** Created by Administrator on 2018/8/20.** 要处理的问题*/
@ToString
@Data
@AllArgsConstructor
public class Trouble {private Integer number;}
2.2 定义解决问题的抽象类
/*** Created by Administrator on 2018/8/20.** 责任链抽象类*/
public abstract class Support {/*** 责任链的名字*/private String name;/*** 责任链的下一个节点*/private Support nextSupport;public Support(String name) {this.name = name;}/*** 执行责任链的下一个节点*/public Support setNextSupport(Support nextSupport){this.nextSupport = nextSupport;return nextSupport;}/*** 解决问题的抽象方法,供子类实现*/protected abstract boolean resolve(Trouble trouble);/*** 解决问题的步骤*/public final void support(Trouble trouble){if (resolve(trouble)){haveDone(trouble);} else if (this.nextSupport != null){this.nextSupport.support(trouble);} else {failDone(trouble);}}/*** 解决问题后执行的方法*/protected void haveDone(Trouble trouble){System.out.println(String.format("%s have been resolved by %s .", trouble, this));}/*** 未能解决问题执行的方法*/protected void failDone(Trouble trouble){System.out.println(String.format("%s can't be resolved .", trouble));}
}
2.3 定义处理类实现类
2.3.1 不处理任何数字的类
/*** Created by Administrator on 2018/8/20.** 该类什么也不处理*/public class NoSupport extends Support {public NoSupport(String name) {super(name);}@Overrideprotected boolean resolve(Trouble trouble) {return false;}
}
2.3.2 只处理小于给定数字的类
/*** Created by Administrator on 2018/8/20.** 只处理小于定义的数字*/
public class LessSupport extends Support{private Integer lessNumber;public LessSupport(String name, Integer lessNumber) {super(name);this.lessNumber = lessNumber;}@Overrideprotected boolean resolve(Trouble trouble) {return trouble.getNumber() < this.lessNumber;}
}
2.3.3 只处理指定数字
/*** Created by Administrator on 2018/8/20.** 只能处理特定的数字*/
public class SpecialSupport extends Support {/*** 指定只能处理的数字*/private Integer specialNumber;public SpecialSupport(String name, Integer specialNumber) {super(name);this.specialNumber = specialNumber;}@Overrideprotected boolean resolve(Trouble trouble) {return trouble.getNumber().equals(this.specialNumber);}
}
2.3.4 只处理奇数
/*** Created by Administrator on 2018/8/20.* <p>* 处理奇数*/
public class OddSupport extends Support {public OddSupport(String name) {super(name);}@Overrideprotected boolean resolve(Trouble trouble) {return trouble.getNumber() % 2 == 0 ;}
}
至此,责任链节点定义完毕
2.4 运行
2.4.1 main
/*** Created by Administrator on 2018/8/20.*/
public class Main {public static void main(String[] args) {//首先定义节点Support noSupport = new NoSupport("A");Support lessSupport = new LessSupport("B",10);Support oddSuuport = new OddSupport("C");Support specialSuuport = new SpecialSupport("D",30);noSupport.setNextSupport(lessSupport).setNextSupport(oddSuuport).setNextSupport(specialSuuport);//执行noSupport.support(new Trouble(5));}
}
2.4.2 运行结果
Trouble(number=5) have been resolved by com.chainofresponsibility.LessSupport@270421f5 .
至此,责任链模式演示完毕;
3.模式分析
3.1 角色解析
在责任链模式中,一共登场了3个角色:
- 处理者接口
- 具体的处理者实现类
- 请求者
我们在编写责任链模式时要注意者三个角色;
3.2 模式对比
责任链模式使得每个处理类只关注自己要处理的场景,处理工作更加专注;如果不符合,则抛到下一个处理节点,我们不必指定专门的处理类,更加弱化了处理的角色;
在这里我想到了策略模式,我们往往需要利用工厂来根据传入的参数指定特定的处理类来处理,而责任链模式实际上恰恰的弱化了这一环节,我们不必知道交给链条的问题到底是哪一个节点来处理;
4. 动态改变责任链
...待续...