》》
----- 当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负责处理时,就需要推卸责任。
在这种情况下,我们可以考虑将多个对象组成一条职责链,然后按照它们的职责链上的顺序一个一个
地找出到底应该谁来负责处理。
----- 使用 Chain of Responsibility 模式可以弱化“请求方”和“处理方”之间的关联关系,让双方各自都成为
独立复用的组件。此外,程序还可以应对其他需求,如根据需求不同,负责处理的对象也会发生变化
的这种需求。
------ 当一个人被要求做什么事情时,如果他可以做就自己做,如果不能做就将“要求”转给另外一个人。
下一个人如果可以自己处理,就自己做;如果也不能自己处理,就再转给另外一个人。。。。。这就
是推卸责任模式。
》》示例程序如下

》》Trouble 类
package chainofresponsibility;
/**
* Trouble 类是表示发生的问题的类。
* number 是问题编号;通过 getNumber 方法可以获取问题编号
*/
public class Trouble {
private int number; // 问题编号
public Trouble(int number){ // 生成问题
this.number = number;
}
public int getNumber(){ // 获取问题编号
return number;
}
public String toString(){ // 代表问题的字符串
return "[Trouble"+number + "]";
}
}
》》Support 类
package chainofresponsibility;
/**
* Support 类是用来解决问题的抽象类,它是职责链上的对象。
*
*
*/
public abstract class Support {
private String name ; // 解决问题的实例的名字
private Support next; // 要推卸给的对象
public Support(String name){
this.name = name ; // 生成解决问题的实例
}
public Support setNext(Support next){ // 设置要推卸给的对象
this.next = next;
return next;
}
public final void support(Trouble trouble){ // 解决问题的步骤
if(resolve(trouble)){
done(trouble);
}else if(next != null){
next.support(trouble);
}else{
fail(trouble);
}
}
public String toString(){ // 显示字符串
return "["+ name +"]";
}
protected abstract boolean resolve(Trouble trouble); // 解决问题的方法
protected void done(Trouble trouble){ // 解决
System.out.println(trouble + "is resolved by " + this + ".");
}
protected void fail(Trouble trouble){ // 未解决
System.out.println(trouble + " cannot be resolved");
}
}
》》 NoSupport 类
package chainofresponsibility;
/**
* NoSupport 类是 Support 类的子类。
* NoSupport 类的 resolve 方法总是返回 false 。即它是一个永远“不解决问题” 的类
*/
public class NoSupport extends Support{
public NoSupport(String name){
super(name);
}
@Override
protected boolean resolve(Trouble trouble) { // 解决问题的方法
return false; // 自己什么也不处理
}
}
》》LimitSupport 类
package chainofresponsibility;
/**
* LimitSupport 类解决编号小于 limit 值的问题
*/
public class LimitSupport extends Support{
private int limit ; // 可以解决编号小于 limit 的问题
public LimitSupport(String name, int limit ){ // 构造函数
super(name);
this.limit = limit;
}
@Override
protected boolean resolve(Trouble trouble) { // 解决问题的方法
if(trouble.getNumber() <limit){
return true;
}else{
return false;
}
}
}
》》OddSupport 类
package chainofresponsibility;
/**
* OddSupport 类解决奇数编号的问题
*/
public class OddSupport extends Support{
public OddSupport(String name ){ // 构造函数
super(name);
}
@Override
protected boolean resolve(Trouble trouble) { // 解决问题的方法
if(trouble.getNumber() % 2 ==1 ){
return true;
}else{
return false;
}
}
}
》》SpecialSupport 类
package chainofresponsibility;
/**
* SpecialSupport 类只解决指定编号的问题
*/
public class SpecialSupport extends Support{
private int number; // 只能解决指定编号的问题
public SpecialSupport(String name , int number){ // 构造函数
super(name);
this.number = number;
}
@Override
protected boolean resolve(Trouble trouble) { // 解决问题的方法
if(trouble.getNumber() == number){
return true;
}else{
return false;
}
}
}
》》Main 类
package chainofresponsibility;
/**
* 测试程序
*/
public class Main {
public static void main(String[] args){
Support alice = new NoSupport("Alice");
Support bob = new LimitSupport("Bob",100);
Support charlie = new SpecialSupport("Charlie",429);
Support diana = new LimitSupport("Diana",200);
Support elmo = new OddSupport("Elmo");
Support fred = new LimitSupport("Fred",300);
// 形成职责链
alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);
// 制造各种问题
for(int i = 0 ; i < 500 ; i += 33){
alice.support(new Trouble(i));
}
}
}
》》Chain of Responsibility 模式中的登场角色
------ Handler (处理者)
Handler 角色定义了处理请求的接口(API)。Handler 角色知道“下一个处理者”是谁,如果自己
无法处理请求,它会将请求转给“下一个处理者”。当然“下一个处理者”也是 Handler 角色。在上面的
程序中, 由 Support 类扮演此角色。负责处理请求的是 support 方法。
------- ConcreteHandler(具体的处理者)
ConcreteHandler 角色是处理请求的具体角色。在上面的程序中,由 NoSupport 、 LimitSupport 、
OddSupport 、 SpecialSupport 等各个类扮演此角色。
------- Client (请求者)
Clinet 角色是第一个 ConcreteHandler 角色发送请求的角色。在上面的程序中,由 Main 类扮演
此角色。
》》扩展思路的要点
--------- 弱化了发送请求的人和处理请求的人之间的关系
Chain of Responsibility 模式的最大优点就在于它弱化了发出请求的人(Client 角色)和处理请求
的人(ConcreteHandler 角色)之间的关系。Client 角色向第一个 ConcreteHandler 角色发出的请求,
然后请求会在职责链中传播,直到某个 ConcreteHandler 角色处理该请求。
如果不使用该模式,就必须有某个伟大的角色知道“谁应该处理什么请求”。而让“发出请求的人”
知道“谁应该处理该请求”并不明智,因为如果发出请求的人不得不知道处理请求的人各自的责任分担
情况,就会降低其作为可复用的组件的独立性。
-------- 可以动态地改变职责链
使用 Chain of Responsibility 模式,通过委托推卸责任,就可以根据情况变化动态地重组织职责链。
-------- 专注于自己的工作
每个 ConcreteHandler 角色都专注于自己所负责的处理。当自己无法处理时,ConcreteHandler 角色
将会改当前问题丢给下一个处理者来解决。
--------- 推卸请求会导致处理延迟
使用 Chain of Responsibility 模式可以推卸请求,直到找到合适的处理请求的对象,这样确实提高了
程序的灵活性,但是该模式会导致处理请求发生延迟。
上面的问题是需要权衡的问题。如果请求和处理者之间的关系是确定的,而且需要非常快的处理速度
时,不使用 Chain of Responsibility 模式会更好。
》》相关的设计模式
-------- Composite 模式
Handler 角色经常会使用 Composite 模式。
-------- Command 模式
有时候会使用 Command 模式向 Handler 角色发送请求。
本文介绍了职责链模式(Chain of Responsibility),当程序无法直接决定处理对象时,可将多个对象组成职责链按顺序找出处理者。该模式能弱化请求方和处理方关联,还可动态改变职责链,但会导致处理延迟。文中给出示例程序,并提及相关设计模式。
1016

被折叠的 条评论
为什么被折叠?



