Skip to main content

Template Method Pattern: Don't Call Us, We'll Call You!


So far, the Template Method has been my most used design pattern. That is the reason why this post is quite long. J

Definition from Wiki

The Template Method defines the program skeleton of an algorithm in a method, deferring some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure.

Template Method UML.svg

A Real World Use Case

Imagine that you have many different kinds of documents. You want to generate a pdf file from a corresponding word template. Each type has its own small modifications but the main process for document generating is the same.

We apply the Template Method for this case. We define a final method including some steps (such as preparing for content, generating file) at a superclass. There are three possibilities for these steps at subclasses:
  1. Must be overridden: abstract methods.
  2. Not mandatory to be overridden: default protected methods.
  3. Can not be overridden: default private methods.

Dissecting the Pattern

Simply, we can see the following attributes:
  • Superclass has a "template" method which should be final to prevent subclasses from reworking the algorithm.
  • The template method defines the sequence of steps, each represented by a method.
  • Some methods are handled by the superclass.
  • Some methods are handled by subclasses.

Benefit? Why?

  • Reuse, avoiding duplication, and subclasses just need to implement a couple of methods.
  • The algorithm lives in one place and code changes only need to be made there.

Hooked on Template Method

A hook is a method that is declared in the abstract class but only given an empty or default implementation. This gives subclasses the ability to "hook into" the algorithm at various points if they wish; a subclass is also free to ignore the hook.

The Hollywood Principle

We allow low-level components to hooking themselves into a system, but high-level components determine when they are needed, and how. In other words, the high-level components give the low-level components a "don't call us, we'll call you" treatment.

Template Method & Strategy: Inheritance vs. Delegation

Template Method and Strategy both solve the problem of separating a generic algorithm from a detailed context. They can often be used interchangeably. However, Template Method uses inheritance to solve the problem, whereas Strategy uses composition/delegation.

Inheritance was a highlight feature in the early days of OO. That is, given some class that did something almost useful to us, we could create a subclass and change only the bits we didn't like. However, inheritance was very easy to overuse; that is a reason why we have heard of a lot of "Favor object composition over class inheritance". That is, inheritance is a very strong relationship. Derivatives are inextricably bound to their base classes. Anyway, that doesn't mean we should avoid using inheritance.

The Strategy provides one extra benefit over the Template Method. Whereas the Template Method allows a generic algorithm to manipulate many possible detailed implementations, the Strategy by fully conforming to Dependency Injection Principle (DIP) allows each detailed implementation to be manipulated by many different generic algorithms.

References:
[1]. Bert Bates, Kathy Sierra, Eric Freeman, and Elisabeth Robson, Head First Design Patterns, A Brain-Friendly Guide
[2]. Robert C. Martin, Agile Software Development, Principles, Patterns, and Practices
[3]. https://en.wikipedia.org/wiki/Template_method_pattern

Comments

Popular posts from this blog

Attribute 'for' of label component with id xxxx is not defined

I got the warning in the log file when I have used the tag <h:outputLabel> without attribute " for " in xhtml file. It was really polluting my server log files. The logged information actually makes sense anyway! We could find an answer as the following: "Having h:outputLabel without a "for" attribute is meaningless. If you are not attaching the label, you should be using h:outputText instead of h:outputLabel." However, these solutions are not possible just for my situation. Instead of using h:outputText for only displaying text, my team has used h:outputLabel too many places. We were nearly in our release time (next day) so it is quite risky and takes much efforts if we try to correct it. Because the style (with CSS) is already done with h:ouputLabel . The alternative by adding attribute " for " the existing h:outputLabel is not reasonable either. I really need to find another solution. Fortunately, I came across a way if I cha...

4 Remarkable Notes for JSF Apps Using HTML5

In the previous post , I've already shared with you how my team consults clients by using a HTML prototype. This post is about the used technologies for reusing the provided HTML template and communicating with backend. What is the issue when using HTML elements with Primefaces components? Primefaces is a great extension for developing JSF web apps. However, it is really frustrating in case we have to make it work with an existing HTML template. Why? - Primefaces has its own theme for styling. - Primefaces changes the HTML structure. Therefore, that would be a huge effort to use the Primefaces' components to replicate the elements of the HTML template; especially it is impossible for images drawing by " canvas " tag. That requires us to find a better approach. Since Java EE 7 (introducing JSF 2.2 included), it supports to use HTML5 elements . The idea is that JSF components don't effect the style and HTML structure, so we can easily reuse the provided HTM...

Google I/O '18

Here are my top 5 impressions on this conference. Gmail - live sentence suggestion It looked like the way developers use intelligent code completion in an IDE when coding. Google Photos: converting a photo has a document to pdf I have a paid app on my iPad called "Scanner for Me" but now I can use Google Photos instead. ;) Google Assistant: bot makes a real call to book a restaurant dinner or a hair salon Wow! This feature, for me, is really a big innovation. My team is working so hard on building our bot which is able to have a continued conversation. Google is so good! Google Maps: using Phone's camera to watch the direction When I saw a fox as a cicerone on the demo, I was thinking of Pokémon GO. Google Lens: extract text from images I have heard a story from a friend of me that he had to use his app about "optical character recognition (OCR)" to scan and translate the texts into English whenever he saw texts in China. Google Lens would be ...

Styling Sort Icons Using Font Awesome for Primefaces' Data Table

So far, Primefaces has used image sprites for displaying the sort icons. This leads to a problem if we want to make a different style for these icons; for example, I would make the icon "arrow up" more blurry at the first time the table loading because I want to highlight the icon "arrow down". I found a way that I can replace these icons with Font Awesome icons. We will use "CSS Pseudo-classes" to achieve it. The hardest thing here is that we should handle displaying icons in different cases. There is a case both "arrow up" and "arrow down" showing and other case is only one of these icons is shown. .ui-sortable-column-icon.ui-icon.ui-icon-carat-2-n-s { background-image: none; margin-left: 5px; font-size: 1.1666em; position: relative; } .ui-sortable-column-icon.ui-icon.ui-icon-carat-2-n-s:not(.ui-icon-triangle-1-s)::before { content: "\f106"; font-family: "FontAwesome"; position: ...

Safari (older than 14.1.1) rejects TLS connections of TURN with Let's Encrypt certificates

Summary We could not make a video call successfully on Safari older than 14.1.1. The call kept disconnecting for some seconds. We got the following error in Nginx’s log SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:SSL alert number 48   Root cause The Safari didn’t trust our TLS certificates (certified by Let’s Encrypt) when establishing a TLS connection into our TURN server. It is a known issue that could be found at Bug 219274 - ICE does not resolve for `turns` relay candidates rooted in LetsEncrypt CA . The issue was just recently fixed (end of 2020), therefore old versions of Safari still meet the issues.   Solution In our development environment, we replaced the untrusted certificate with a trusted one. We will warn our customers about this issue in our installation guide. Technical explained WebKit is a browser engine developed by Apple and primarily used in its Safari web browser, as well as all iOS web browsers. The WebRTC of WebKit relied on ...