定义
- 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中
- 使得子类可以不改变算法结构即可重定义该算法的某些特定步骤
类比:就像你制作一杯咖啡的过程:1. 烧水,2. 冲泡咖啡,3. 倒入杯子,4. 加糖或牛奶。每个步骤都是固定的,但具体实现可以变化
应用场景
- 多个类有相同的方法,且逻辑相同,但某些细节需要在子类中实现
- 需要控制子类的扩展行为时
优缺点
- 优点
- 避免代码重复
- 让子类实现算法的特定部分
- 缺点
- 每个不同实现都需要一个子类,会导致类的数量增加
实现代码
// 抽象类
abstract class AbstractClass {
public templateMethod(): void {
this.baseOperation1();
this.requiredOperations1();
this.baseOperation2();
this.hook1();
this.requiredOperations2();
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 requiredOperations2(): void;
protected hook1(): void { }
protected hook2(): void { }
}
// 具体类
class ConcreteClass1 extends AbstractClass {
protected requiredOperations1(): void {
console.log('ConcreteClass1 says: Implemented Operation1');
}
protected requiredOperations2(): void {
console.log('ConcreteClass1 says: Implemented Operation2');
}
}
class ConcreteClass2 extends AbstractClass {
protected requiredOperations1(): void {
console.log('ConcreteClass2 says: Implemented Operation1');
}
protected requiredOperations2(): 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());
console.log('');
console.log('Same client code can work with different subclasses:');
clientCode(new ConcreteClass2());