Template Method

定义:在抽象类中定义关于操作的算法的骨架(相应的操作方法以及这些方法的执行顺序或逻辑),相应的子类可以重写符合自己需求的操作方法。
作用:将通用算法抽象出来,再由子类去重写

  1. /**
  2. * The Abstract Class defines a template method that contains a skeleton of some
  3. * algorithm, composed of calls to (usually) abstract primitive operations.
  4. *
  5. * Concrete subclasses should implement these operations, but leave the template
  6. * method itself intact.
  7. */
  8. abstract class AbstractClass {
  9. /**
  10. * The template method defines the skeleton of an algorithm.
  11. */
  12. public templateMethod(): void {
  13. this.baseOperation1();
  14. this.requiredOperations1();
  15. this.baseOperation2();
  16. this.hook1();
  17. this.requiredOperation2();
  18. this.baseOperation3();
  19. this.hook2();
  20. }
  21. /**
  22. * These operations already have implementations.
  23. */
  24. protected baseOperation1(): void {
  25. console.log('AbstractClass says: I am doing the bulk of the work');
  26. }
  27. protected baseOperation2(): void {
  28. console.log('AbstractClass says: But I let subclasses override some operations');
  29. }
  30. protected baseOperation3(): void {
  31. console.log('AbstractClass says: But I am doing the bulk of the work anyway');
  32. }
  33. /**
  34. * These operations have to be implemented in subclasses.
  35. */
  36. protected abstract requiredOperations1(): void;
  37. protected abstract requiredOperation2(): void;
  38. /**
  39. * These are "hooks." Subclasses may override them, but it's not mandatory
  40. * since the hooks already have default (but empty) implementation. Hooks
  41. * provide additional extension points in some crucial places of the
  42. * algorithm.
  43. */
  44. protected hook1(): void { }
  45. protected hook2(): void { }
  46. }
  47. /**
  48. * Concrete classes have to implement all abstract operations of the base class.
  49. * They can also override some operations with a default implementation.
  50. */
  51. class ConcreteClass1 extends AbstractClass {
  52. protected requiredOperations1(): void {
  53. console.log('ConcreteClass1 says: Implemented Operation1');
  54. }
  55. protected requiredOperation2(): void {
  56. console.log('ConcreteClass1 says: Implemented Operation2');
  57. }
  58. }
  59. /**
  60. * Usually, concrete classes override only a fraction of base class' operations.
  61. */
  62. class ConcreteClass2 extends AbstractClass {
  63. protected requiredOperations1(): void {
  64. console.log('ConcreteClass2 says: Implemented Operation1');
  65. }
  66. protected requiredOperation2(): void {
  67. console.log('ConcreteClass2 says: Implemented Operation2');
  68. }
  69. protected hook1(): void {
  70. console.log('ConcreteClass2 says: Overridden Hook1');
  71. }
  72. }
  73. /**
  74. * The client code calls the template method to execute the algorithm. Client
  75. * code does not have to know the concrete class of an object it works with, as
  76. * long as it works with objects through the interface of their base class.
  77. */
  78. function clientCode(abstractClass: AbstractClass) {
  79. // ...
  80. abstractClass.templateMethod();
  81. // ...
  82. }
  83. console.log('Same client code can work with different subclasses:');
  84. clientCode(new ConcreteClass1());
  85. console.log('');
  86. console.log('Same client code can work with different subclasses:');
  87. clientCode(new ConcreteClass2());

参考资料

  1. 通俗易懂系列 | 设计模式(一):模板模式
  2. 模板方法模式