Let's take a very easy-to-understand scenario to implement the Template method pattern. Imagine the case of a travel agency, say, Dev Travels. Now how do they typically work? They define various trips to various locations and come up with a holiday package for you. A package is essentially a trip that you, as a customer, undertakes. A trip has details such as the places visited, transportation used, and other factors that define the trip itinerary. This same trip can be customized differently based on the needs of the customers. This calls for the Template Method pattern, doesn't it?
Design Considerations:
AbstractClass
interface that defines a tripday1
, day2
, and day3
, assuming that it's a three-day long weekend trip, and also define the return journeyitinerary()
Template Method will actually define the trip's itineraryConcreteClasses
that would help us customize trips differently based on the customer's needsLet's develop an application in Python v3.5 and implement the preceding use case. We start with the abstract class, Trip
:
Trip
class. It is an interface (Python's abstract base class) that defines the details such as the transportation used and places to visit on different days.setTransport
is an abstract method that should be implemented by ConcreteClass
to set the mode of transportation.day1()
, day2()
, day3()
abstract methods define the places visited on the given day.itinerary()
Template Method creates the complete itinerary (the algorithm, in this case, the trip). The sequence of the trip is to first define the transportation mode, then the places to visit on each day, and the returnHome
.The following code implements the scenario of Dev Travels:
from abc import abstractmethod, ABCMeta class Trip(metaclass=ABCMeta): @abstractmethod def setTransport(self): pass @abstractmethod def day1(self): pass @abstractmethod def day2(self): pass @abstractmethod def day3(self): pass @abstractmethod def returnHome(self): pass def itinerary(self): self.setTransport() self.day1() self.day2() self.day3() self.returnHome()
We have also developed certain classes that represent the concrete class:
VeniceTrip
and MaldivesTrip
—that implement the Trip
interfaceVeniceTrip
and MaldivesTrip
both implement setTransport()
, day1()
, day2()
, day3()
, and returnHome()
Let's define the concrete classes in Python code:
class VeniceTrip(Trip): def setTransport(self): print("Take a boat and find your way in the Grand Canal") def day1(self): print("Visit St Mark's Basilica in St Mark's Square") def day2(self): print("Appreciate Doge's Palace") def day3(self): print("Enjoy the food near the Rialto Bridge") def returnHome(self): print("Get souvenirs for friends and get back") class MaldivesTrip(Trip): def setTransport(self): print("On foot, on any island, Wow!") def day1(self): print("Enjoy the marine life of Banana Reef") def day2(self): print("Go for the water sports and snorkelling") def day3(self): print("Relax on the beach and enjoy the sun") def returnHome(self): print("Dont feel like leaving the beach..")
Now, let's talk about the travel agency and tourists who want to have an awesome vacation:
TravelAgency
class represents the Client
object in this examplearrange_trip()
method that provides customers with the choice of whether they want to have a historical trip or beach tripitinerary()
Template Method and the trip is arranged for the tourists as per the choice of the customersThe following is the implementation for the Dev travel agency and how they arrange for the trip based on the customer's choice:
class TravelAgency: def arrange_trip(self): choice = input("What kind of place you'd like to go historical or to a beach?") if choice == 'historical': self.trip = VeniceTrip() self.trip.itinerary() if choice == 'beach': self.trip = MaldivesTrip() self.trip.itinerary() TravelAgency().arrange_trip()
The output of the preceding code should look as follows:
If you decide to go on a historical trip, this will be the output of the code:
3.135.184.239