책임 연쇄 패턴 -> 핸들러들의 체인을 따라 요청을 전달할 수 있게 해주는 행동 디자인 패턴
#문제
// 핸들러 인터페이스
interface Handler {
setNext(handler: Handler): Handler;
handle(request: string): string;
}
/**
* 핸들러 인터페이스를 따르는 기초 핸들러 클래스
* 다음 핸들러에 대한 참조를 저장하는 레퍼런스와 setter를 가짐
* handle 메서드에서 기본적인 행동을 정의하고 다음 핸들러에 요청을 넘겨주게 됨
*/
abstract class AbstractHandler implements Handler
{
private nextHandler: Handler;
public setNext(handler: Handler): Handler {
this.nextHandler = handler;
return handler;
}
public handle(request: string): string {
if (this.nextHandler) {
return this.nextHandler.handle(request);
}
return null;
}
}
/**
* 기초 핸들러 인터페이스를 따르는 구상 핸들러
* 각 핸들러는 요청을 받으면 요청을 처리할지, 요청을 넘겨줄지를 결정하게 됨
*/
class MonkeyHandler extends AbstractHandler {
public handle(request: string): string {
if (request === 'Banana') {
return `Monkey: I'll eat the ${request}.`;
}
return super.handle(request);
}
}
class SquirrelHandler extends AbstractHandler {
public handle(request: string): string {
if (request === 'Nut') {
return `Squirrel: I'll eat the ${request}.`;
}
return super.handle(request);
}
}
class DogHandler extends AbstractHandler {
public handle(request: string): string {
if (request === 'MeatBall') {
return `Dog: I'll eat the ${request}.`;
}
return super.handle(request);
}
}
// 클라이언트 코드
function clientCode(handler: Handler) {
const foods = ['Nut', 'Banana', 'Cup of coffee'];
for (const food of foods) {
console.log(`Client: Who wants a ${food}?`);
const result = handler.handle(food);
if (result) {
console.log(` ${result}`);
} else {
console.log(` ${food} was left untouched.`);
}
}
}
const monkey = new MonkeyHandler();
const squirrel = new SquirrelHandler();
const dog = new DogHandler();
// 핸들러 체인 형성
monkey.setNext(squirrel).setNext(dog);
console.log('Chain: Monkey > Squirrel > Dog\n');
clientCode(monkey);
/*
Client: Who wants a Nut?
Squirrel: I'll eat the Nut.
Client: Who wants a Banana?
Monkey: I'll eat the Banana.
Client: Who wants a Cup of coffee?
Cup of coffee was left untouched.
*/
console.log('');
console.log('Subchain: Squirrel > Dog\n');
clientCode(squirrel);
/*
Client: Who wants a Nut?
Squirrel: I'll eat the Nut.
Client: Who wants a Banana?
Banana was left untouched.
Client: Who wants a Cup of coffee?
Cup of coffee was left untouched.
*/
출처:
https://refactoring.guru/ko/design-patterns/chain-of-responsibility