cft

Design Patterns Saga: The Paper Doll

Overview of Template Method Design Pattern


user

Gene Zeiniss

3 years ago | 6 min read

As a child, I loved paper dolls. The figures are cut out of paper, with separate clothes, also made of paper, that are usually held onto the dolls by paper folding tabs. The reason I loved them so much was that I could very easily create new looks for my dolls and try them on.

My dolls changed their appearance a few times a day. I’ve come up with the new look idea, drawn it, cut it, and voila, the outfit is ready. Although I don’t regret being a software developer, I have no idea why I never became a fashion designer.

So, let’s talk about paper doll outfit creation in Java language.

Outfit Creation Speaking Java

Think about a paper doll. Let’s call her Tanja. Tanja lives in a country with four complete seasons, let’s say Denmark. And she is devoted to fashion clothing (I would say, Tanja is a fashionista but according to Urban Dictionary, this term sometimes has a negative connotation, and real fashionista does not believe in trends).

Suppose you want to create some summer outfit for her. I’m thinking of a white blouse with denim shorts and neutral lace-up flats. Now that you have a clear mental image in your mind, you can draw and cut it. The next season is autumn. The autumn outfit idea is a sweater, ripped jeans, and vaja sneakers. Draw it, cut it…

Have you noticed some common steps in outfit creation processes? Of course, you have. Some of these steps are implemented differently depending on which season outfit you are creating.

Each outfit has a different top, bottom, and footwear. At the same time both outfits should be drawn and cut in the same way. You can model this situation by an Outfit class with a method that knows the general set of steps of the process. The details for the different Outfits are implemented in inherited classes. Let’s take a look at a data-diagram for outfit creation:

Oh, I see here an opportunity to refresh Java object-oriented key concepts. I pretty like the idea of refreshing knowledge. Hmmm. I feel like I’m about to open a column “What do we know about anything?”. Ok, now it’s official. The topic of the day is an abstraction.

What Do We Know About Abstraction?

According to Oxford, Abstraction is “the quality of dealing with ideas rather than events”. In other words, it’s something that exists, but you have only a vague concept about it.

Think about online shopping. All you need to know to buy something from the website is to select the item and to place the order. After a certain waiting period, the goodies you ordered will find you (or not).

Pretty simple. I mean, you don’t need to really know how the process works from the other side of the website. Where the goods are stored; who prepares the order for you; how the goods are delivered etc. This magic is called abstraction.

The same concept is used by Java, as in other object-oriented languages.

Abstraction in Java in a Few Words

The main goal of Abstraction in Java is to handle complexity by hiding unnecessary details from the user. That enables complex logic implementation on top of the provided abstraction without understanding or even thinking about all the hidden complexity.

You just need to know which methods of the object are available to call and which input parameters are needed to trigger a specific operation.

Take a look at our data-diagram. When you are creating a daily look for Tanja, using software, you should only describe the top, bottom, and the footwear of the outfit. You really don’t have to be skilled at drawing or papercutting.

So far so good.

If you are familiar with Design Patterns, you will recognize the elements of the Template Method pattern in outfit diagram. But if you are new, you can find a brief overview of the previous chapter of Design Patterns Saga to start with. Ok, let’s get it straight, this article is about the Template Method.

Template Method Pattern

The Template Method, it’s a behavioral design pattern that defines a skeleton of an algorithm in a base-class and defers the implementation of some steps to sub-classes, without changing the overall algorithm’s structure.

This pattern is used when you notice you have few classes with very similar functionality in order of operations. You remember the steps; describe the outfit, draw it, cut it… And again. This is our use-case!

Hey, what time is it? It’s code time! N-o-t! Kidding. I recently watched a Borat movie for the first time. My world is not the same anymore. Ok, back to reality, I just want to show you some Java code on how you can implement the template method.

Template Method Pattern Implementation

Let’s take a look at the Outfit base-class.

public abstract class Outfit {
public void createDailyLook() {
describeTop();
describeBottom();
describeFootwear();
drawDescribedOutfit();
cutDrawnOutfit();
}
public abstract void describeTop();
public abstract void describeBottom();
public abstract void describeFootwear();
public void drawDescribedOutfit() { log.info("drawing outfit according to selections"); }
public void cutDrawnOutfit() { log.info("cutting drawn outfit"); }
}

The Outfit abstract class declares methods that act as steps of a daily look creation algorithm. It also defines the actual template method createDailyLook(). This method calls the describe methods in a specific order. Some of the steps are declared as abstract, others have a default implementation.

Concrete Outfit classes can override all the steps of the base-class, except for the template method itself (otherwise, what’s the point of the template?). Consider making the template method final to prevent subclasses from overriding it.

This ensures consistency in the steps of creating a daily look outfit and reduces redundant code. This is how the season outfit sub-classes could look like.

public class SummerOutfit extends Outfit {
@Override
public void describeTop() { log.info("white blouse");}
@Override
public void describeBottom() { log.info("denim shorts");}
@Override
public void describeFootwear() { log.info("neutral lace up flats");}
}


public class AutumnOutfit extends Outfit {
@Override
public void describeTop() { log.info("white sweater"); }
@Override
public void describeBottom() { log.info("ripped jeans"); }
@Override
public void describeFootwear() { log.info("veja sneakers"); }
}

I’ve nothing to add, it’s pretty clear.

Now, to check the Template Method in action, create Outfit Service. Let’s go pattern crazy and use the Factory pattern for concrete class creation. Just because we can! 😎

public class SeasonOutfitFactory {
public Outfit createOutfit(Season season) {
return Match(season).of(
Case($(Season.SUMMER), new SummerOutfit()),
Case($(Season.AUTUMN), new AutumnOutfit()),
Case($(), () -> {
log.info("the outfit for provided {} season is undefined", season.toString().toLowerCase());
return null;
})
);
}
}


@RequiredArgsConstructor
public class OutfitService {

private final SeasonOutfitFactory seasonOutfitFactory;

public void createOutfit(Season season) {
Outfit seasonOutfit = seasonOutfitFactory.createOutfit(season);
seasonOutfit.createDailyLook();
}
}

When you call to createOutfit() method the following logs will be printed for summer:

SummerOutfit - white blouse
SummerOutfit - denim shorts
SummerOutfit - neutral lace-up flats
Outfit - drawing outfit according to selections
Outfit - cutting drawn outfit

And these for autumn:

AutumnOutfit - white sweater
AutumnOutfit - ripped jeans
AutumnOutfit - veja sneakers
Outfit - drawing outfit according to selections
Outfit - cutting drawn outfit

That’s all! Clean and simple!

Now, Tanja’s autumn outfit is ready. But you’re not completely satisfied with the final look. You realize that this outfit is missing something. Something warm. It’s autumn in Denmark, you know. The white sweater and ripped jeans could really use a camel coat.

Consider a few things: How do we add outerwear to the outfit? How do we do this dynamically, without changing base-class definitions? Sounds like a challenge? Yes it i

Upvote


user
Created by

Gene Zeiniss

Java developer, backend guild master at a fintech startup, blogger (http://medium.com/@genezeiniss) 🤓


people
Post

Upvote

Downvote

Comment

Bookmark

Share


Related Articles