Home Simplify Template Method (Behavioral Pattern)
Post
Cancel

Simplify Template Method (Behavioral Pattern)

🌑 Why Template Method Pattern

was once working on a movie classification application. She needed to develop an algorithm to categorize the application into comedy, horror, and action movies. In the first iteration of the application, Spidey must get the JSON data from the API & parse it. By examining content attributes, assign the movie to a specific category.

After successfully launching the first version, Spidey asked to support a legacy system that returns content in XML & CSV formats. Also, the application has a glitch that the Giant Spider-based movie should be categorised as Horror, not Family.

She developed a new version that handled data from a legacy system. Later, she realized that all three classes had much in common code-wise. The code for handling the various data formats (JSON, XML, CSV) was different but processing & analysing the data has identical code.

Instantly, The Template method pattern clicked in Spidey’s mind, which she could use here for code reusability.

🌥️ Outline

The Template method pattern is a behavioural design pattern that defines steps for an algorithm in a superclass. A subclass can override specific steps to provide the desired behaviour without changing the execution flow of the algorithm.

The method that decides the execution sequence of an algorithm is called the Template method.

Template - A structure to be followed for an algorithm.

🌜Template In Real World

if you visualise the tea-making process, it is a Template. Making tea involves several steps. Each step can be customised based on your taste.

You can change the ingredients to change the taste of the tea, but the process will remain the same. Instead of matcha powder if you add Moringa powder then a Moringa tea is ready to drink.

🌕 Solution

breaks the movie analysing process into five steps. Each step represents a method in the interface MovieAnalyzer.

To provide the default implementation of methods a DefaultMovieAnalyzer class is created by . The class has a definition for verifyMovie & analyzeMovie methods. Of course, she also added the definition of the Template method startMovieAnalyze which is responsible for invoking these individual methods into a sequence to accomplish the goal.

Now turn is for subclasses to define the rest of the methods based on requirements. created two subclasses one to handle the data from the modern server and the other one for Legacy. She has created two classes “ModernMovieAnalyzer” and “LegacyMovieAnalyzer” to provide implementation based on data formats.

With this approach, Spidey was able to remove code duplicity as verifyMovie and analyzeMovie methods only exist in the base class.

Some languages like Swift provide features to add default implementation in interfaces. You can use the feature and avoid adding unnecessary inheritance of DefaultMovieAnalyzer.

Do you Know
You can add a method with the empty definition in the base class before or after any step. It gives flexibility to subclass to add extensions in the process. This empty method is called hook.

Template Method Componentes

Base class or Interface:
A Base class or Interface that defines the template method. It also declares all the methods required for the algorithm. It is a skeleton of the algorithm. A combination of MovieAnalyzer & DefaultMovieAnalyzer is this.
Template Method:
This is the heart of the design pattern and consists of a series of method calls (either abstract or concrete) that make up the algorithm’s steps. It should be declared as final to prevent subclasses from changing the algorithm’s structure.
Concrete Subclasses:
Subclasses that extend the base class and provide a variant of implementation by overriding the methods defined in the superclass. It provides customization in the algorithm without impacting its flow. ModernMovieAnalyzer & LegacyMovieAnalyzer are concrete subclasses.
Hook Methods(Optional):
A hook is an optional step with an empty body. These methods are placed before and after crucial steps of algorithms, providing subclasses with additional extension points for an algorithm.

🌟 Where To Apply

    Use Template Method to implement a process have sequential steps
It can be applied when implementing a process with a standard sequence of steps, representing a step by a method.

The sign-up process can be structured using a template method, with predefined steps like providing Personal Information, User Interests, and User Skills.

    Use Template Method where a process dealing with various inputs
As Spidey used when dealing with diverse input formats for the process of movie analyzing. A Data mining application dealing with various data formats can use a template method for the mining process. Example: Data mining across XML, JSON, and text formats.

🌓 To Gain Something, You Have To Lose

Design patterns are solutions to common problems in software design. They offer a structured approach to solving problems, like a blueprint. It is not that the problem cannot be solved without a design pattern, however, a solution using a design pattern will provide better flexibility, scalability and n number of benefits. However, every benefit comes with a trade-off. Let’s explore what that means in the context of the Template Method pattern.

Reusability vs Flexibility

Template pattern supports code reusability by moving common code in the base class. On the other hand, It creates a rigid hierarchy of classes. You cannot change the flow and steps in the derived class.

For example, In the above case, if a company want to introduce a Pizza with no cheese and no sauce (Healthy Pizza). There is no way to remove the steps here. However, in code, there is a way to achieve this by overriding the method and leaving it empty but then you break the Liskov substitute principle.

Cohesion vs Coupling

The template pattern enhances code cohesion by centralizing common logic in a single location. As Spidey move all the logic to analyze a movie in a single place MovieAnalyzer. The complete code for analyzing movies is encapsulated with the MovieAnalyzer module.

However, on the other hand, it creates a tight coupling between the base class and the subclasses. Any change in the base class will impact the derived class. While designing the base class you need to take care of the interface it should not be too fat.

🌚 Some Interesting Facts

   Template Method & Factory Method
Apart from method in a name, both patterns have one more thing in common i.e. design:

Template MethodFactory Method

The Template pattern provides a skeletal structure for an algorithm, allowing subclasses to override specific steps without changing the algorithm’s overall structure. Similarly, the Factory method defines an interface for creating objects but lets subclasses decide which specific class to instantiate.

The Factory Method pattern is to object creation what the Template Method pattern is to behaviour execution.

   Template Method & Strategy Pattern
The template method is used when a standard behaviour exists for a process. The standard behaviour is defined in the base class and variants of the behaviour can be added in the subclass.
Strategy pattern is also used to handle multiple variants of a process. However, each variant has independent (No common) implementation. Sorting in most of the language is implemented through this pattern.

    Hollywood Principle & Template Method
The Hollywood principle is the design principle that high-level components dictate the low-level components “Don’t call us, we’ll call you”. i.e. the high-level components determine how the low-level systems are needed and when they are needed.
This relates to the Template Method pattern in the sense that the abstract base class calls the operations of a subclass and not the other way around. This is apparent in our high-level class MovieAnalyzer has control over the algorithm for analysing movies, and calls on the subclasses only when they are needed for the implementation of a method. Clients of movie analysing will depend on the MovieAnalyzer abstraction rather than a concrete modern or legacy, which reduces dependencies in the overall system.

The Hollywood Principle comes from the Hollywood philosophy where the production houses call actors if there is any role for the actor.

Code Example (Swift)

Interface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
enum MovieCategory {
    case horror
    case comedy
    case family
    case action
}

struct MovieDetail {
    let name: String
    let category: MovieCategory?
    let releaseYear: Int
    let summary: String
}

protocol MovieAnalyzer {
    func movieNetworkRequest(url: String)
    func fetchMovieDetail() -> [String: Any]
    func parseMovieDetail(rawDetail: [String: Any]) -> MovieDetail
    func verifyMovie(movieDetail: MovieDetail) -> Bool
    func analyzeMovie(movieDetail: MovieDetail) -> MovieCategory
    func startMovieAnalyze()
}

Template Method:

1
2
3
4
5
6
7
8
9
func startMovieAnalyze(url: String) {
	let request = self.movieNetworkRequest(url: url)
    let rawData = self.fetchMovieDetail()
    let moviewModel = parseMovieDetail(rawDetail: rawData)
    let isValidMovie = self.verifyMovie(movieDetail: moviewModel)
    if isValidMovie {
        let category = analyzeMovie(movieDetail: moviewModel)
    }
}

Concrete Subclasses:

1
2
3
4
5
6
7
8
9
10
11
class ModernMovieAnalyzer: MovieAnalyzer {
    func movieNetworkRequest(url: String) {
        //Prepare Modern Server network request
    }
    func fetchMovieDetail() -> [String: Any] {
        //Fetch movie detail from server
    }
    func parseMovieDetail(rawDetail: [String: Any]) -> MovieDetail {
        //Parse movie Detail
    }
}
This post is licensed under CC BY 4.0 by the author.

Game - Connect Balls

SwiftUI - Create Expandable List (Section Approach)

Comments powered by Disqus.