Design Patterns Demystified - Template Design Pattern
In the first article of this series, we take a look at demystifying the Template design pattern by exploring the why, what, how, and where.
Join the DZone community and get the full member experience.Join For Free
Welcome to the Design Patterns Demystified (DPD) series, in this edition we are going to discuss Template Design Pattern. So let us understand the why, how, what, and where of Template Design Pattern.
Let us understand first, why we need this pattern with the help of an example. Let's you are building a reusable library which is orchestrating the operation of buying an item on an e-commerce platform. Now, irrespective of what you are buying, you will follow the same sequence of steps like building your cart, adding an address, filling in payment details, and then finishing the payment. The details in these steps will vary based on what you are buying, how much you are buying, the delivery address, and the preferred mode of payment, but the complete orchestration of steps remains the same.
Now, imagine you are given the responsibility of building a re-usable library that is supposed to be used by many different e-commerce platforms to enable purchase of products on their platform. Here, each e-commerce platform will have different flows and requirements in terms of all the factors described above, but eventually, all of them want to follow the same sequence of steps. So how do you ensure that your library remains open for limited extension but closed for modification of the overall behavior and at the same time, every platform also respects the contract provided by the library? The answer is, Template Design pattern.
Let us understand what template design is. In template design, we create an abstraction/specification which specifies the overall behavior (and we make sure that this overall behavior is immutable) and we declare the inner steps of the overall behaviors but don't provide details of the inner steps, because, if you recall, every platform/consumer may have their own implementation of these inner steps.
Let us use the same example as described above to show how we can implement this pattern. The example uses Java, but you are free to choose your object-oriented programming language for this.
The first step is to create the
EcommercePaymentEngine specification where we provide the orchestration but leave the inner details to the adopters to implement. Here is how it looks:
Let'ss walk through what is happening here. We have an abstract class called
EcommercePaymentEngine. This has a final method as
pay(). This is the orchestrator method. Notice that it is intentionally made final because we don't want any implementer to tamper with the orchestrator. This orchestrator function is wrapping up all the steps which are universal to any e-commerce platform (at least in the utopian world of this post) but those methods are abstract. It is up to the e-commerce platforms to provide details on those behaviors as those behaviors will vary from one platform to another.
Now, let us assume that two e-commerce giants, Foo and Bar, have agreed to use your awesome
EcommercePaymentEngine. The implementation at Foo's end would look like:
and, expectedly, the implementation at Bar's end would look like:
Now Foo and Bar can just invoke the pay method in their platform and that should be it. They will get the complete template implemetnation of EcommercePaymentEngine's
pay() method out of the box. Below is a sample implementation of their invocation:
This will produce the following output:
The template design pattern comes handy for collaboration and promotes the whole concept of modularity and re-usability. The other visible benefits of it are code de-duplication, easy version management, etc. If you are working on a large project, there will be plenty of opportunities for implementing this pattern because such large projects tend to have a lot of duplication and overlap of functionalities. Having said that, we should not overuse this pattern; otherwise we will end up in a dependency-mess of tightly coupled templates.
The complete code of this tutorial is available at this link.
Opinions expressed by DZone contributors are their own.