Design Pattern: Template Method and Chipotle

Design Pattern: Template Method and Chipotle

Design patterns in life and Ruby – gain an intuitive understanding of OO design patterns by linking them with real-life examples.

 

Template Method is the most commonly used design pattern in programming and real life.

Before we dive into details of the pattern, let’s learn an important life lesson:

Chipotle 101: How to Order in Chipotle.

There are four steps involved:

  1. Choose a “vessel”: Burrito vs. Bowl vs. Tacos vs. Salad
  2. Add meat: Chicken vs Steak vs. Barbacoa vs. Carnitas vs. Vegetarian
  3. Add toppings: Tomato vs. Corn vs. Green Chili vs. Red Chili
  4. Add extras & drinks: Chips vs. Guacamole vs. Salsa vs. Beer vs. Soda

 

For example, my go-to order is Bowl + Steak + (Tomato + Corn) + Guacamole and my friend Amber’s go-to order is Burrito + Chicken + (Green Chili + Red Chili) + (Chips + Soda).

 

If we code our go-to orders in Ruby, they will look like:

When we order, we put everything we want into the vessel and return the stuffed vessel.

Unfortunately, Amber and I decide to be on a diet for a while. And we decide that when we order from Chipotle, we can only get tomato as a topping and no extras. So our choices are limited to:

  1. Vessel: Burrito vs. Bowl vs. Tacos vs. Salad
  2. Meat: Chicken vs. Steak vs. Barbacoa vs. Carnitas vs. Vegetarian
  3. Toppings: Tomato
  4. No extras & drinks

 

During the diet, our go-to orders have to be modified to:

  • Sihui: Bowl + Steak + Tomato + No extras & drinks
  • Amber: Burrito + Chicken + Tomato + No extras & drinks

 

Putting our orders down in Ruby, we have the following:

 

Noticing both our orders have the exact same toppingsextras, and order methods, it makes sense to pull them out as a parent class, DietOrder, and have DietOrderSihui and DietOrderAmber inherit from it.

 

Now our friend Ben wants to join our Chipotle Diet Club, and he likes Tacos with Carnitas. Then his order will be:

 

Ta-da, you just learned the Template Method design pattern! 🎉 🎉

Don’t believe me?

Take a look at the definition of the Template Method.

The Template Method pattern is a behavioral design pattern that:

– defines the program skeleton of an algorithm in an operation,

– deferring some steps to subclasses.

 

It lets one redefine certain steps of an algorithm without changing the algorithm’s structure.

Doesn’t this sound exactly like what we just did with our DietOrder and SihuiDietOrder/AmberDietOrder/BenDietOrder?

DietOrder defines the order skeleton: one can only get tomato as a topping and no extras & drinks, and one orders by picking a vessel and putting everything inside the chosen vessel.

SihuiDietOrder/AmberDietOrder/BenDietOrder redefine the vessel and meat depending on our personal preferences.

 

Let’s say a month passed by, and Amber and I followed our diet strictly. We decided to reward ourselves with cheat days!

On a cheat day, we have soda as our drinks. 🍺🍺🍺 And each of us can decide which day of the month to be our cheat days.

Since Ben is new to the club, he decides to stick to the diet strictly for a bit longer.

Let’s see how it looks in Ruby:

In DietOrder, we ask if today is a cheat day. If so, we can have Soda as an extra. Otherwise, there are no extras. And by default, today is not a cheat day.

Amber and I get to define our own cheat days:

Since Ben is sticking with the diet strictly, he doesn’t get a cheat day.

His class doesn’t need to change.

The is_cheat_day? method is a hook.

A hook provides a way for a subclass to implement an optional part of an algorithm.

 

If the subclass doesn’t care about the part, it can skip it and use the default implementation in the parent class.

In our case, is_cheat_day? is optional. SihuiDietOrder and AmberDietOrder implement it because we want to have a cheat day each month. But Ben does not want to have a cheat day. So BenDietOrder skips implementing is_cheat_day? and uses the default one from DietOrder, which always returns false.

 

Two Object-oriented Design Principles

The Template Method uses two important object-oriented design principles:

1. Encapsulate what varies.

In our case, the varying parts are vesselmeat, and is_cheat_day?. We encapsulate them in subclasses. For the parts that don’t vary, toppings and extras, we leave them in the parent class.

2. The Hollywood Principle: Don’t call us, we’ll call you.

Yes, The Hollywood Principle is a real thing.

In Hollywood, movie producers will tell actors: “Don’t call us, we’ll call you if we find a role that fits you.”

In programming, low-level components can participate in the computation, like AmberDietOrder defining its own is_cheat_day?, but the high-level components control when and how, like DietOrder calls is_cheat_day? within extras.

 

Takeaways:

One definition =>

The Template Method pattern is a behavioral design pattern that

– defines the program skeleton of an algorithm in an operation,

– deferring some steps to subclasses.

It lets one redefine certain steps of an algorithm without changing the algorithm’s structure.

Two Design Principles =>

1. Encapsulate what varies.

2. The Hollywood Principle: Don’t call us, we’ll call you.

Or…

 you can just take away a Chipotle order 🥙 🌮 🌯

 

Next time, we take our design & food adventure to 🍰🍰🍰

 

Subscribe so you won’t miss it!

Enjoyed the article?

My best content on Software Design, Rails, and Career in Dev. Delivered weekly.

Unsubscribe at anytime. I'll never spam you. Powered by ConvertKit

Leave a Comment