定义
责任链模式,是一种行为设计模式,它允许你将请求沿着处理者链传递,直到某个处理者负责处理该请求。
这种模式让多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。
UML 类图
typescript 实现
1. 定义处理器接口
interface Handler {
setNext(h: Handler): void;
handle(request: any): any;
}
2. 基础处理器实现
class BaseHandler implements Handler {
private next: Handler | null = null;
setNext(h: Handler) {
this.next = handler;
return handler;
}
public handle(request: any): any {
if(this.next) {
return this.next.handle(request);
}
return null;
}
}
3. 创建具体处理者
class ConcreteHandler1 extends BaseHandler {
public handle(request: any): any {
if(request === "A") {
return `ConcreteHandler handled request ${request}`);
} else {
return super.handle(request);
}
}
}
class ConcreteHandler2 extends BaseHandler {
public handle(request: any): any {
if(request === "B") {
return `ConcreteHandler2 handled request ${request}`;
} else {
return super.handle(request);
}
}
}
class DefaultHandler extends BaseHandler {
public handle(request: any): any {
return `DefaultHandler handled request ${requset}`;
}
}
4. 使用示例
function clientCode(handler: Handler) {
const requests = ["A", "B", "C"];
for(const request of requests) {
console.log(`Client: Who can handle ${request}`);
const result = handler.handle(request);
if(result) {
console.log(` ${result}`);
} else {
console.log(` ${request} was left unhandled.`);
}
}
}
// 组装责任链
const handler1 = new ConcreteHandler1();
const handler2 = new ConcreteHandler2();
const defaultHanlder = new DefaultHandler();
handler1.setNext(handler2).setNext(defaultHandler);
clientCode(handler1);
通用实现
// 公共代码
export abstract class ChainHandler<T> {
protected next: ChainHandler<T> | null = null;
public setNext(handler: ChainHandler<T>): ChainHandler<T> {
this.next = handler;
return handler;
}
public handle(arg: T): any | null {
if(this.next) {
return this.next.handle(arg);
}
return null;
}
}
// 私有代码,URL 类
class URL {
constructor(url: string) {
this.url = url;
}
}
// 私有代码,各种 Filter
class TxtFilter extends ChainHandler<URL> {
handle(arg: URL): any {
if(arg.url.endsWith("txt")) {
return true;
} else {
return super.handle(arg);
}
}
}
class ImgFilter extends ChainHandler<URL> {
handle(arg: URL): any {
if(arg.url.endsWith("png")) {
return true;
} else {
return super.handle(arg);
}
}
}
class DefaultFilter extends ChainHandler<URL> {
handle(arg: URL): any {
return false;
}
}
// 私有代码,使用示例
const txtFilter = new TxtFilter();
const imgFilter = new ImgFilter();
const defaultFilter = new DefaultFilter();
txtFilter.setNext(imgFilter).setNext(defaultFilter);
const boolean = txtFilter.handle(new URL("https://flywen.top/demo.txt"));
console.log(boolean);