美文网首页
Chain of Responsibility模式(责任链模式)

Chain of Responsibility模式(责任链模式)

作者: 涅槃快乐是金 | 来源:发表于2020-12-19 09:11 被阅读0次

责任链模式(Chain of Responsibility Pattern):多个对象组成一条职责链,然后按照它们在职责链上的顺序处理请求。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

介绍

  • 意图:发送者与接收者解耦,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
  • 主要解决:职责链上的处理者负责处理请求,发送者无须关心请求的处理细节和请求的传递。
  • 何时使用:在处理消息的时候以过滤很多道。
  • 如何解决:拦截的类都实现统一接口。
  • 应用实例:JS 中的事件冒泡
  • **优点: **
    1、降低耦合度
    2、简化了对象。使得对象不需要知道链的结构。
    3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
    4、增加新的请求处理类很方便。
  • 缺点:
    1、不能保证请求一定被接收。
    2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
    3、可能不容易观察运行时的特征,有碍于除错。

示例

Trouble.ts 表示发生问题的类,带有事件编号
export default class Trouble {
    private num: number;//问题编号
    constructor(num: number) {//生产问题
        this.num = num;
    }
    public toString(): string {
        return `[Trouble ${this.num}]`
    }
    public getNum(): number {
        return this.num;
    }
}
Support.ts 解决问题的抽象类
import Trouble from "./Trouble";

export default abstract class Support {
    private name: string;
    private next: Support;
    constructor(name: string) {
        this.name = name;
    }
    public setNext(next: Support): Support {
        this.next = next;
        return next;
    }
    public support(trouble: Trouble): void {
        if (this.resolve(trouble)) {
            this.done(trouble);
        } else if (this.next != null) {
            this.next.support(trouble);
        } else {
            this.fail(trouble);
        }
    }
    public toString(): string {
        return `[${this.name}]`;
    }
    protected abstract resolve(trouble: Trouble): boolean;
    protected done(trouble: Trouble): void {//解决
        console.log(`${trouble.toString()} is resolved by ${this.toString()}`);
    }
    protected fail(trouble: Trouble): void {//未解决
        console.log(`${trouble.toString()} canot be resolved`);
    }
}
NoSpport.ts 用于解决问题的类(永不解决)
import Support from "./Support";
import Trouble from "./Trouble";

export default class NoSupport extends Support {
    constructor(name: string) {
        super(name);
    }
    protected resolve(trouble: Trouble): boolean {//解决问题的方法
        return false;                             //自己不处理
    }
}
LimitSupport.ts 用于解决问题的类(仅解决编号小于指定值的问题)
import Support from "./Support";
import Trouble from "./Trouble";

export default class LimitSupport extends Support {
    private limit: number;
    constructor(name: string, limit: number) {
        super(name);
        this.limit = limit;
    }
    protected resolve(trouble: Trouble): boolean {//解决问题的方法
        if (trouble.getNum() < this.limit) {
            return true;//正常应该为解决问题的方法
        } else {
            return false;                             //自己不处理
        }
    }
}
OddSupport.ts 用于解决问题的类(仅解决奇数编号的问题)
import Support from "./Support";
import Trouble from "./Trouble";
/**
 * 解决奇数问题
 */
export default class OddSupport extends Support {
    constructor(name: string) {
        super(name);
    }

    protected resolve(trouble: Trouble): boolean {//解决问题的方法
        if (trouble.getNum() % 2 == 1) {
            return true;//正常应该为解决问题的方法
        } else {
            return false;                             //自己不处理
        }
    }
}
SpecialSupport.ts 用于解决问题的类(仅解决指定编号的问题)
import Support from "./Support";
import Trouble from "./Trouble";

export default class SpecialSupport extends Support {
    private num: number;
    constructor(name: string, num: number) {
        super(name);
        this.num = num;
    }

    protected resolve(trouble: Trouble): boolean {//解决问题的方法
        if (trouble.getNum() == this.num) {
            return true;//正常应该为解决问题的方法
        } else {
            return false;                             //自己不处理
        }
    }
}
index.ts
import NoSupport from "./NoSupport";
import Support from "./Support";
import LimitSupport from "./LimitSupport";
import SpecialSupport from "./SpecialSupport";
import OddSupport from "./OddSupport";
import Trouble from "./Trouble";

const alice: Support = new NoSupport("Alice");
const bob: Support = new LimitSupport("Bob", 100);
const charlie: Support = new SpecialSupport("Charlie", 429);
const diana: Support = new LimitSupport("Diana", 200);
const elmo: Support = new OddSupport("Elmo");
const fred: Support = new LimitSupport("Fred", 300);

alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);
for (let i = 0; i < 500; i += 33) {
    alice.support(new Trouble(i));
}
result
[Trouble 0] is resolved by [Bob]
[Trouble 33] is resolved by [Bob]
[Trouble 66] is resolved by [Bob]
[Trouble 99] is resolved by [Bob]
[Trouble 132] is resolved by [Diana]
[Trouble 165] is resolved by [Diana]
[Trouble 198] is resolved by [Diana]
[Trouble 231] is resolved by [Elmo]
[Trouble 264] is resolved by [Fred]
[Trouble 297] is resolved by [Elmo]
[Trouble 330] canot be resolved
[Trouble 363] is resolved by [Elmo]
[Trouble 396] canot be resolved
[Trouble 429] is resolved by [Charlie]
[Trouble 462] canot be resolved
[Trouble 495] is resolved by [Elmo]

类图

类图

角色

  • Handler(处理者)
    Handler定义了处理请求的具体接口,Handler知道下一个处理者是谁,当无法处理时会把事件转给下一个处理者,当然先一个处理者也是Handler角色
  • ConcreteHandler(具体的处理者)
    ConcreteHandler是处理请求的具体角色
  • Client(请求者)
    事件发起者

相关文章

网友评论

      本文标题:Chain of Responsibility模式(责任链模式)

      本文链接:https://www.haomeiwen.com/subject/ofjggktx.html