/**
* 추상클래스에서 알고리즘의 단계가 되는 여러 메서드들을 선언하며, 이들을 순차적으로 호출하는 템플릿 메서드도 선언을 하게 됨
*/
abstract class AbstractClass {
/**
* 템플릿 메서드에서 알고리즘의 호출 순서를 결정하게 됨
*/
public templateMethod(): void {
this.baseOperation1();
this.requiredOperations1();
this.baseOperation2();
this.hook1();
this.requiredOperation2();
this.baseOperation3();
this.hook2();
}
/**
* 일부 메서드들은 추상 클래스 단계에서 구현을 할 수 있음
*/
protected baseOperation1(): void {
console.log('AbstractClass says: I am doing the bulk of the work');
}
protected baseOperation2(): void {
console.log('AbstractClass says: But I let subclasses override some operations');
}
protected baseOperation3(): void {
console.log('AbstractClass says: But I am doing the bulk of the work anyway');
}
/**
* 서브클래스에서 구현해야하는 메서드들
*/
protected abstract requiredOperations1(): void;
protected abstract requiredOperation2(): void;
/**
* 빈 상태로 정의되어 있으며 상속을 받는 클래스들이 선택적으로 구현가능한 메서드들을 hook이라 부름
*/
protected hook1(): void { }
protected hook2(): void { }
}
/**
* 구상 클래스에서 추상 클래스의 인터페이스를 구현
*/
class ConcreteClass1 extends AbstractClass {
protected requiredOperations1(): void {
console.log('ConcreteClass1 says: Implemented Operation1');
}
protected requiredOperation2(): void {
console.log('ConcreteClass1 says: Implemented Operation2');
}
}
class ConcreteClass2 extends AbstractClass {
protected requiredOperations1(): void {
console.log('ConcreteClass2 says: Implemented Operation1');
}
protected requiredOperation2(): void {
console.log('ConcreteClass2 says: Implemented Operation2');
}
protected hook1(): void {
console.log('ConcreteClass2 says: Overridden Hook1');
}
}
/**
* 클라이언트 코드
*/
function clientCode(abstractClass: AbstractClass) {
abstractClass.templateMethod();
}
console.log('Same client code can work with different subclasses:');
clientCode(new ConcreteClass1());
/*
AbstractClass says: I am doing the bulk of the work
ConcreteClass1 says: Implemented Operation1
AbstractClass says: But I let subclasses override some operations
ConcreteClass1 says: Implemented Operation2
AbstractClass says: But I am doing the bulk of the work anyway
*/
console.log('');
console.log('Same client code can work with different subclasses:');
/*
AbstractClass says: I am doing the bulk of the work
ConcreteClass2 says: Implemented Operation1
AbstractClass says: But I let subclasses override some operations
ConcreteClass2 says: Overridden Hook1
ConcreteClass2 says: Implemented Operation2
AbstractClass says: But I am doing the bulk of the work anyway
*/
clientCode(new ConcreteClass2());
출처:
https://refactoring.guru/ko/design-patterns/template-method