《图解设计模式》读书笔记6-2 Chain of Responsibility模式

1. 简介

Chain of Responsibility模式是责任链模式,模式的核心就是转移责任。就好比你要去政府部门办事,A部门说你去B部门问问,B部门说你去C部门问问,C部门说我们不管...在找到正确的部门解决问题之前,这些部门一直在踢皮球。

在程序中,确实需要这样的场景:将多个对象组成一个责任链,一个请求过来了,按照它们在责任链上的顺序一个一个找出到底由谁来负责

这个模式的好处在于弱化请求方和处理方的关联关系,让双方都可以成为独立复用的组件。

2. 示例程序

类图

代码

Trouble类是表示问题的类,其属性nubmer是问题编号。

Support以及其子类表示解决问题的类,Support是抽象父类,具体的Support类表示解决特定问题的类。

public class Trouble {
    private int number;             // 问题编号
    public Trouble(int number) {    // 生成问题
        this.number = number;
    }
    public int getNumber() {        // 获取问题编号
        return number;
    }
    public String toString() {      // 代表问题的字符串
        return "[Trouble " + number + "]";
    }
}
//解决问题的抽象父类
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;
    }
    //定义解决问题的步骤
    // 其中使用了抽象方法resolve,这个方法由子类实现,这是Template Method方法的体现。
    public 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.");
    }
}
//什么问题都不解决
public class NoSupport extends Support {
    public NoSupport(String name) {
        super(name);
    }
    protected boolean resolve(Trouble trouble) {     // 解决问题的方法
        return false; // 自己什么也不处理
    }
}
// 可以解决编号小于limit的问题
public class LimitSupport extends Support {
    private int limit;                              
    public LimitSupport(String name, int limit) {   // 构造函数
        super(name);
        this.limit = limit;
    }
    protected boolean resolve(Trouble trouble) {    // 解决问题的方法
        if (trouble.getNumber() < limit) {
            return true;
        } else {
            return false;
        }
    }
}
//解决编号为奇数的问题
public class OddSupport extends Support {
    public OddSupport(String name) {                // 构造函数
        super(name);
    }
    protected boolean resolve(Trouble trouble) {    // 解决问题的方法
        if (trouble.getNumber() % 2 == 1) {
            return true;
        } else {
            return false;
        }
    }
}
//只能解决编号为number的问题
public class SpecialSupport extends Support {
    private int number;                                
    public SpecialSupport(String name, int number) {    // 构造函数
        super(name);
        this.number = number;
    }
    protected boolean resolve(Trouble trouble) {        // 解决问题的方法
        if (trouble.getNumber() == number) {
            return true;
        } else {
            return false;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Support noSupportMan   = new NoSupport("noSupportMan");
        Support lt2Man = new LimitSupport("lt2Man", 2);
        Support specialFor5Man = 
            new SpecialSupport("specialFor5Man", 5);
        Support lt10Man   = new LimitSupport("lt10Man", 10);
        Support oddMan    = new OddSupport("oddMan");
        Support lt15Man    = new LimitSupport("lt15Man", 15);
        // 一层一层深入设置职责链条
        noSupportMan
            .setNext(lt2Man)
            .setNext(specialFor5Man)
            .setNext(lt10Man)
            .setNext(oddMan)
            .setNext(lt15Man);
        // 解决各种问题
        for (int i = 0; i < 17; i++) {
            noSupportMan.support(new Trouble(i));
        }
    }
}
//结果
[Trouble 0] is resolved by [lt2Man].
[Trouble 1] is resolved by [lt2Man].
[Trouble 2] is resolved by [lt10Man].
[Trouble 3] is resolved by [lt10Man].
[Trouble 4] is resolved by [lt10Man].
[Trouble 5] is resolved by [specialFor5Man].
[Trouble 6] is resolved by [lt10Man].
[Trouble 7] is resolved by [lt10Man].
[Trouble 8] is resolved by [lt10Man].
[Trouble 9] is resolved by [lt10Man].
[Trouble 10] is resolved by [lt15Man].
[Trouble 11] is resolved by [oddMan].
[Trouble 12] is resolved by [lt15Man].
[Trouble 13] is resolved by [oddMan].
[Trouble 14] is resolved by [lt15Man].
[Trouble 15] is resolved by [oddMan].
[Trouble 16] cannot be resolved.

3. 模式的角色和类图

角色

  • Handler(处理者):定义了处理请求的接口,这个角色知道下一个Handler是谁,如果自己处理不了就会交给下一个Handler处理。本例中,由Support类扮演此角色。
  • ConcreteHandler(具体的处理者):实现了具体的处理方法。由NoSupport、LimitSupport、OddSupport、SpecialSupport扮演此角色。
  • Client(请求者):向处理者发送问题请求的角色,本例中由Main类扮演此角色。

类图

4. 思路拓展

  • 弱化了发出请求的人和处理请求的人的关系

  • 可以动态改变职责链

  • 专注于自己的工作

  • 模式的缺点:责任被传递,请求会延迟

原文地址:https://www.cnblogs.com/qianbixin/p/10953138.html