«

»

Sep 22

Print this Post

Design patterns: template method

Chapter eight of the book is about template method pattern. It’s another way of encapsulation. The examples shows how to encapsulate piece of algorithms so the sub-classes can hook themselves right into computation any time they want. We learn a new design principle too!

Book example

First example is a real one from real life! ;) We implement code which makes a coffee or tea :) At the beginning we’re presented with code:

#
public class Coffee {
  
  public function prepareRecipe() {
    $this->boilWater();
    $this->brewCoffeeGrinds();
    $this->pourInCup();
    $this->addSugarAndMilk();    
  }

  private function boilWater() {
    echo "Boiling water\n";
  }
  
  private function brewCoffeeGrinds() {
    echo "Dripping coffee through filter\n";
  }

  private function pourInCup() {
    echo "Pouring into cup\n";
  }
  
  private function addSugarAndMilk() {
    echo "Adding sugar and milk\n";
  }
}
#
public class Tea {
  
  public function prepareRecipe() {
    $this->boilWater();
    $this->steepTeaBag();
    $this->pourInCup();
    $this->addLemon();    
  }

  private function boilWater() {
    echo "Boiling water\n";
  }
  
  private function steepTeaBag() {
    echo "Steeping the tea\n";
  }

  private function pourInCup() {
    echo "Pouring into cup\n";
  }
  
  private function addLemon() {
    echo "Adding lemon\n";
  }
}

Probably many of the readers are worried about the code duplication. And indeed, when we have code duplication it’s a signal we need to clean-up the design. We’re asked to draft possible class hierarchy. At first it’s probably made of three classes. The base class has prepareRecipe(), boilWater() and pourInCup() methods because they’re clearly common parts of code for Coffee and Tea classes and they don’t differ anyhow of each other. Two other classes are the ones presented above: Coffee and Tea. However with the new hierarchy contain less code and extend the brand new base class. They overwrite prepareRecipe() method and have two new methods each class (brewCoffeeGrinds(), addSugarAndMilk(), steepTeaBag() and addLemon()).

That was a move in the right direction but we can do better! Next step in the book is taking a look at the bigger picture. We abstracted boilWater() and pourInCup() methods but the ones left in sub-classes are practically the same! They just apply to different beverages. So, basically we can abstract prepareRecipe().
Brewing coffee grinds and steeping tea bag are, in general, brewing a beverage. And adding sugar, milk and lemon is nothing else than adding condiments the the beverage. At the end our parent class prepareRecipe() looks like this:

#
public function prepareRecipe() {
  $this->boilWater();
  $this->brew();
  $this->pourInCup();
  $this->addCondiments();
}

Then in the same class we define abstract methods brew() and addCondiments(), so the sub-classes have to implement them. We remove overwritten prepareRecipe() methods from Coffee and Tea classes and implement there only those two new methods. Here you can find final and working code.

As you suspect the prepareRecipe() method in our super class is nothing else than an example of template method design pattern usage. The book’s diagram and definition are as follows:

A template method pattern's diagram

A template method pattern’s diagram

The Template Method Pattern defines the skeleton of an algorithm in a method, deferring some steps to sub-classes. Template Method let’s sub-classes redefine certain steps of an algorithm without changing the algorithm’s structure.

After learning the definition and diagram we read about pretty common practice of using hooks methods together with the template method pattern. Hooks are methods injected into our template method to make it more flexible/extensible. Going back to our coffee&tea example a hook could be added to prepareRecipe() method and depending on its result the addCondiments() method would be executed. New parent class code written in this way looks like:

#
abstract class CaffeineBeverageWithHook {

  public function prepareRecipe() {
    $this->boilWater();
    $this->brew();
    $this->pourInCup();
    
    if( $this->customerWantsCondiments() ) {
      $this->addCondiments();
    }
  }

// ...

  public function customerWantsCondiments() {
    return true;
  }
}

The sub-classes can overwrite the hook method and modify it but there isn’t “a must” to do so. In the code examples package, I put link to earlier, you’ll find working example of using hooks. I must admit that hooks in object-oriented way are even more useful in my eyes than hooks I’ve seen in some PHP code-bases.

After introduction to hooks we’re presented with another design principle: The Hollywood Principle. This time it’s pretty easy to remember: “Don’t call us, we’ll call you”. It helps us with preventing “dependency rot” in our code-base. Dependency rot happens when high-level class is depending on low-level classes which are depending on sideways components which are depending on low-level classes, and so on. When rot sets in, no one can easily tell the way a system is designed.
With the new principle we allow low-level components to hook themselves into a system, but high-level components determine when they are needed, and how. How does it work in our template method example? CaffeineBeverage has control over algorithm for the recipe, and calls on the sub-classes when they’re needed for an implementation of a method. This class is our high-level component which tells Coffee and Tea classes “don’t call us, we’ll call you”. The sub-classes never calls the abstract class directly. Clients of beverages will depend only on CaffeineBeverage abstraction rather than a concrete sub-classes. And this is how we reduce dependencies in the overall system.

After the new design principle authors show more examples of template method pattern implementations in Java. Not all of them depends on inheritance. There is an example with Comparable interface and compareTo() template method. The Java Arrays class is responsible for different arrays’ manipulation such as sorting. Arrays class implements all required steps of sorting but it let’s other classes decide on how elements are compared to each other.
The other two Java examples are examples of different classes and their hooks. JFrame class and its paint() hook method and Applet class with several hooks:

  • init() allows the applet to do whatever it wants to initialize the applet the first time,
  • start() allows the applet to do something when the applet is just about to be displayed on the web page,
  • stop() if the user goes to another page the stop() hook is used and the applet can do whatever it needs to do to stop its actions,
  • destroy(),
  • paint().

Other examples

Putting “php template method” in Google results in links to web pages which occurs the most often when you’re looking for examples of design patterns in PHP. Two of them describes the same abstract example of displaying books titles and authors. There is also well-known blog of author I’ve mentioned before: she had similar idea to mine — write about design patterns learn from Head First. Design patterns. It was a nice to see Sitepoint name within the results links (I really enjoy reading their articles). Example there describes how to use template method for rendering different jQuery sliders. It’s nice and more practical example than the ones described shortly before. One more nice example with step after step explanation is about implementing classes representing tweet text.

Separate paragraph needs to be written about hooks mentioned in the chapter. In all examples: books and the one I found on the Internet you read about them as method in the abstract class which can be overwritten by sub-classes. It’s clearly object-oriented and PHP wasn’t an object-oriented language. Therefore, you can find many PHP applications with the idea of hooks. In Wikia we use MediaWiki code and there is quite a long list of hooks you can hook into. WordPress since version 2.1 split hooks into two groups: filter and action hooks. Another blog application, Drupal, had its own hooks list but since version 8 they started using many Symfony’s components as well as its event listeners which allows to hook into Symfony application. Symfony, Zend, CodeIgniter and many other PHP frameworks uses different approaches to allow a developer to hook into their core code. But these hooks are a little bit different than hooks explained during learning template method design pattern. So let me stop at this point.

Other design patterns

Here is the list of described by me design patterns:

Permanent link to this article: https://blog.lukaszewski.it/2013/09/22/design-patterns-template-method/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>