Template Method

Allowing subclasses to vary a common algorithm

Imagine a workday morning. You get up, go through the regular routine, but put on nice clothes today because you have a presentation to give. Next morning, you wake up, do the regular routine, put on presentable clothes, but not as spiffy as yesterday. Oh, and you hit a bakery on the way to work because you wanted to celebrate someone's achievement. On your day off, you wake up, brush teeth, put on sports outfit and go for a run.
The Template Method pattern is about a routine that is happening every time, but allowing for slight variations. In this case, an abstract class Morning would have a getReady() method, with the following items:
  • shutOffAlarm()
  • brushTeeth()
  • shower()
  • getDressed()
  • eatBreakfast()
  • headToThePlaceOfMorningActivity()
  • purchaseSomethingOnTheWay()
And then for MondayMorning, method getDressed can have specific outfit for a day busy with mornings. And for a class SaturdayMorning, the method shutOffAlarm could do nothing since you have no alarm on weekends. Each subclass of Morning still goes throud the getReady method, just with its own variations.
The code example looks at the way an e-mail is composed. One e-mail is sent to the CEO of a company, it has many parts making it an official document easy to read and with lots of details. Another e-mail is a quick note to a friend. Both classes inherit from an abstract class Email, and both go through the compose method's routine, but the e-mail to a friend skips a bunch of formalities and goes straight to the details.
  abstract class Email {
    compose(): void {
      this.salutation();
      this.summary();
      this.discussion();
      this.figures();
      this.closingStatements();
      this.signature();
      this.contactInfo();
    }
    protected abstract salutation(): void; //needs to be overwritten in child class
    protected summary(): void {}
    protected abstract discussion(): void; //needs to be overwritten in child class
    protected figures(): void {}
    protected closingStatements(): void {}
    protected signature(): void {}
    protected contactInfo(): void {}
  }

  class EmailToCEO extends Email {
    salutation(): void {
      console.log("Dear Mr. CEO");
    }
    summary(): void {
      console.log("Everything is great");
    }
    discussion(): void {
      console.log(
        "Since you have been our CEO and making such great decisions, our profits increased."
      );
    }
    figures(): void {
      console.log(
        "Here are three tables that show how much more money we are making."
      );
    }
    closingStatements(): void {
      console.log("In summary, all is well");
    }
    signature(): void {
      console.log("Sincerely yours, your best worker.");
    }
    contactInfo(): void {
      console.log("You can contact me at 555-5555");
    }
  }

  class EmailToFriend extends Email {
    salutation(): void {
      console.log("yo!");
    }
    discussion(): void {
      console.log("let's have a party!");
    }
    contactInfo(): void {
      console.log;
    }
  }
Test code:
  console.log("Email to CEO:");
  let c = new EmailToCEO();
  c.compose();
  console.log("\nEmail to a friend:");
  let f = new EmailToFriend();
  f.compose();
Result:
Email to CEO:
Dear Mr. CEO
Everything is great
Since you have been our CEO and making such great decisions, our profits increased.
Here are three tables that show how much more money we are making.
In summary, all is well
Sincerely yours, your best worker.
You can contact me at 555-5555

Email to a friend:
yo!
let's have a party!
Use this patterns when the steps among several processes are common and it is easy to separate those steps and override implementation for each individual case.