责任链模式


23种设计模式

1.什么是责任链模式

责任:什么是责任,对于Java中的类来说,需要解决某一个问题,就需要调用这个方法。换句话说,拥有这个方法的类有责任解决这个问题。
所以,对于类,其方法就是责任。
责任链:责任链就是以什么顺序去寻找相应的方法。

责任链模式重要的一点:推卸责任。
在这里推卸责任不是贬义,而是一个褒义。对于类来说,只需要关心自己的责任,而不用关心其他的,当需要调用一个方法解决问题时,如果是自己的责任,那么就调用相应的方法解决。如果不是自己的责任,那么久推卸责任,至于推卸给谁,这是一个策略问题。(后面会讨论)

2.责任链模式的角色

抽象的责任,定义责任应当有什么方法,这些方法规定了责任的查询和方法的调用。责任的查询和方法的执行是抽象方法,由责任的子类去实现。
具体的责任,实现抽象的责任中定义的方法,也是解决问题的具体实现。
责任链接,这里定义了具体的责任如何形成链。

3.例子

3.1 抽象的责任

package chainResponsibility.absHander;

public abstract class AbsHander {

protected Boolean resolve;

private AbsHander next;

public AbsHander(){
this.resolve = Boolean.FALSE;
}

public void execute(AbsHander absHander){
isResolve(absHander);
System.out.println("---"+getName()+"--->");
if(resolve){
System.out.println(absHander.getName()+" problem is resolve by "+getName());
} else {
next.execute(absHander);
}
}

protected abstract String getName();

protected abstract void isResolve(AbsHander absHander);

public AbsHander setNest(AbsHander next){
this.next = next;
return next;
}

}

3.2 具体的责任

package chainResponsibility.implHander;

import chainResponsibility.absHander.AbsHander;

public class Hander1 extends AbsHander{

@Override
protected String getName() {
return "Hander1";
}

@Override
protected void isResolve(AbsHander absHander) {
if(absHander instanceof Hander1){
super.resolve = Boolean.TRUE;
} else {
super.resolve = Boolean.FALSE;
}
}

}
package chainResponsibility.implHander;

import chainResponsibility.absHander.AbsHander;

public class Hander2 extends AbsHander{

@Override
protected String getName() {
return "Hander2";
}

@Override
protected void isResolve(AbsHander absHander) {
if(absHander instanceof Hander2){
super.resolve = Boolean.TRUE;
} else {
super.resolve = Boolean.FALSE;
}
}

}
package chainResponsibility.implHander;

import chainResponsibility.absHander.AbsHander;

public class Hander3 extends AbsHander{

@Override
protected String getName() {
return "Hander3";
}

@Override
protected void isResolve(AbsHander absHander) {
if(absHander instanceof Hander3){
super.resolve = Boolean.TRUE;
} else {
super.resolve = Boolean.FALSE;
}
}

}

3.3 责任链

package chainResponsibility.client;

import chainResponsibility.absHander.AbsHander;
import chainResponsibility.implHander.Hander1;
import chainResponsibility.implHander.Hander2;
import chainResponsibility.implHander.Hander3;

public class Main {

public static void main(String[] args) {
AbsHander h1 = new Hander1();
AbsHander h2 = new Hander2();
AbsHander h3 = new Hander3();

h1.setNest(h2).setNest(h3).setNest(h1);

h1.execute(h3);

h1.execute(h2);

h2.execute(h3);

}

}

3.4结果

---Hander1--->
---Hander2--->
---Hander3--->
Hander3 problem is resolve by Hander3
---Hander1--->
---Hander2--->
Hander2 problem is resolve by Hander2
---Hander2--->
---Hander3--->
Hander3 problem is resolve by Hander3

3.5 环形责任链

package chainResponsibility.client;

import chainResponsibility.absHander.AbsHander;
import chainResponsibility.implHander.Hander1;
import chainResponsibility.implHander.Hander2;
import chainResponsibility.implHander.Hander3;

public class Main {

public static void main(String[] args) {
AbsHander h1 = new Hander1();
AbsHander h2 = new Hander2();
AbsHander h3 = new Hander3();

h1.setNest(h2).setNest(h3).setNest(h1);

h1.execute(h3);

h1.execute(h2);

h2.execute(h3);

h2.execute(h1);

h3.execute(h2);

h3.execute(h1);
}

}

3.6 结果

---Hander1--->
---Hander2--->
---Hander3--->
Hander3 problem is resolve by Hander3
---Hander1--->
---Hander2--->
Hander2 problem is resolve by Hander2
---Hander2--->
---Hander3--->
Hander3 problem is resolve by Hander3
---Hander2--->
---Hander3--->
---Hander1--->
Hander1 problem is resolve by Hander1
---Hander3--->
---Hander1--->
---Hander2--->
Hander2 problem is resolve by Hander2
---Hander3--->
---Hander1--->
Hander1 problem is resolve by Hander1

4.扩展

责任链本身并不复杂,但是对于如何形成最优的责任链,这才是责任链 中最复杂的。
对于责任链,其实就是如何寻找最佳路线的问题,这方面的解决方案有很多。
责任链模式同样可以被改造成双向责任链的寻找方式,以及二叉树的寻找方式以及网格,图的寻找方式。