Chain of Responsibility 模式-----推卸责任模式

本文介绍了职责链模式(Chain of Responsibility),当程序无法直接决定处理对象时,可将多个对象组成职责链按顺序找出处理者。该模式能弱化请求方和处理方关联,还可动态改变职责链,但会导致处理延迟。文中给出示例程序,并提及相关设计模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

》》

     ----- 当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负责处理时,就需要推卸责任。

          在这种情况下,我们可以考虑将多个对象组成一条职责链,然后按照它们的职责链上的顺序一个一个

          地找出到底应该谁来负责处理。

     ----- 使用 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 角色发送请求。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小达人Fighting

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值