1 Chain of Responsibility Pattern 责任链模式
目的:弱化请求方与处理方的关联关系,让双方各自都成为可复用的组件;
实现:拦截的类都实现统一接口,将多个对象组成一条责任链,然后按照他们在职责上的顺序一个一个的找出来谁来负责处理。
1.责任链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递;
2.每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
2 实现
代码场景:手机生产流水线车间里,不同组件的流水线工人会对其安装cpu、camera和ram等部件。
1.被处理对象是手机;
2.抽象处理者是流水线;
3.具体处理者是不同组件的工人。
2.1 代码实现
抽象处理者角色:AssemblyWorker(组装工人)
public abstract class AssemblyWorker {
//责任链关键 下一个工人
protected AssemblyWorker nextWorker;
protected MobilePhone mobilePhone;
public AssemblyWorker(MobilePhone mobilePhone) {
this.mobilePhone = mobilePhone;
}
public abstract void assembling();
//设定下一个工人
public void setNextWorker(AssemblyWorker nextWorker) {
this.nextWorker = nextWorker;
}
}
具体处理者角色:CpuWorker (CPU组装工人)
public class CpuWorker extends AssemblyWorker {
private final String name = "CPU组装工人";
public CpuWorker(MobilePhone mobilePhone) {
super(mobilePhone);
}
@Override
public void assembling() {
if (null == mobilePhone.getCpu()) {
mobilePhone.setCpu("高通骁龙8");
System.out.println(name + "将CPU给手机组装上了");
}
if (null != nextWorker) {
nextWorker.assembling();
}
}
}
具体处理者角色:CpuWorker (摄像头组装工人)
public class CameraWorker extends AssemblyWorker {
private final String name = "摄像头组装工人";
public CameraWorker(MobilePhone mobilePhone) {
super(mobilePhone);
}
@Override
public void assembling() {
if (null == mobilePhone.getCamera()) {
mobilePhone.setCamera("索尼2400万像素摄像头");
System.out.println(name + "将摄像头给手机组装上了");
}
if (null != nextWorker) {
nextWorker.assembling();
}
}
}
具体处理者角色:RamWorker(运行内存组装工人)
public class RamWorker extends AssemblyWorker {
private final String name = "运行内存组装工人";
public RamWorker(MobilePhone mobilePhone) {
super(mobilePhone);
}
@Override
public void assembling() {
if (null == mobilePhone.getRam()) {
mobilePhone.setRam("DDR4 8G 运行内存");
System.out.println(name + "运行内存给手机组装上了");
}
if (null != nextWorker) {
nextWorker.assembling();
}
}
}
2.2 涉及角色
在职责链模式结构图中包含如下几个角色:
Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(如结构图中的 successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。
ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。
2.3 调用
调用者:
public class Client {
public static void main(String[] args) {
//对一个什么都没有的手机进行组装
MobilePhone mp = new MobilePhone();
AssemblyWorker cpuWorker = new CpuWorker(mp);
AssemblyWorker cameraWorker = new CameraWorker(mp);
AssemblyWorker ramWorker = new RamWorker(mp);
cpuWorker.setNextWorker(cameraWorker);
cameraWorker.setNextWorker(ramWorker);
cpuWorker.assembling();
mp.show();
System.out.println("-------------------------");
//对一个已经存在CPU的手机进行组装
MobilePhone mp1 = new MobilePhone();
mp1.setCpu("Intel");
AssemblyWorker cpuWorker1 = new CpuWorker(mp1);
AssemblyWorker cameraWorker1 = new CameraWorker(mp1);
AssemblyWorker ramWorker1 = new RamWorker(mp1);
cpuWorker1.setNextWorker(cameraWorker1);
cameraWorker1.setNextWorker(ramWorker1);
cpuWorker1.assembling();
mp1.show();
}
}
结果:
CPU组装工人将CPU给手机组装上了
摄像头组装工人将摄像头给手机组装上了
运行内存组装工人运行内存给手机组装上了
该手机的CPU为[高通骁龙8],Camera为[索尼2400万像素摄像头],RAM为[DDR4 8G 运行内存]
-------------------------
摄像头组装工人将摄像头给手机组装上了
运行内存组装工人运行内存给手机组装上了
该手机的CPU为[Intel],Camera为[索尼2400万像素摄像头],RAM为[DDR4 8G 运行内存]
参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.