Image for post
Image for post

Learn Design Patterns: Strategy Pattern

Jimmy Farillo
Feb 23, 2017 · 5 min read

The strategy pattern is an alternative to the template method pattern I wrote about in my previous post, providing a different solution to the common programming problem of requiring some variation within an algorithm. Both patterns use polymorphism in their approaches, but while the template method pattern relies on inheritance, the strategy pattern relies on composition and delegation.

Composition

To use the Party example from the post on the template method pattern, you might choose to think about parties as being made up of different parts, such as a venue, guests, supplies, and activities. Modeled in code, these parts could be defined as instance variables with accessor methods.

Composition describes the “has a” relationship between the object and the parts that it is made up of. From this perspective, a Partyhas a” venue, “has a” guests, “has a” supplies, and “has a” activities.

This is in contrast with inheritance, which describes a “is a” relationship. A BirthdayParty “is a” Party.

So another way to look at the different types a Party could be is to think about them in terms of their parts. Here’s an example of a birthday party and a game night party implemented using composition rather than inheritance.

In this example, each instance of Party is instantiated with different parts. Specifically, the array supplies for birthday_party contains a single object of type Food, while game_night contains two objects of type Game. We’ll come back to this example below, when we get into the specifics of the strategy pattern.

Instead of defining different kinds of parties as subclasses of the abstract Party class, instances of Party are made to be different because they are composed of different parts. The advantage of using composition over inheritance is that there is no coupling of subclasses to a superclass in composition, reducing the number of dependencies in your code.

Delegation

Delegation often comes up when composition is used. Delegation is the concept of passing off some work to another object.

There will be some logic involved for inviting our guests to the party, and we could put that logic inside our Party class.

But we could also delegate this task to each guest by placing that logic inside the User class and sending that message to the guest objects.

In the above example, the invite_guests method on the Party class sends the send_invitation message to each guest, which is defined in the User class. The instance of Party also passes a reference of itself, as self, as an argument to send_invitation, allowing the method to know the context in which it should be performed. The logic of how to invite a guest has been passed off to each guest object.

The Strategy Pattern

Now that we’ve discussed composition and delegation, we can use them in the strategy pattern. Let’s Party on! 🎉

You might remember the throw_party method from the previous post about the template method pattern. It contains all the logic necessary for throwing a great party.

We can create variation in that algorithm by delegating the responsibilities to the different parts that compose each party. If you remember, the only parts that differ between birthday parties and game nights are the supplies and the activities, so I’m going to ignore the methods the deal with venue and guests.

The supplies and activities are the objects that compose our Party. All supplies that make up our Party should implement the buy method, whether each object is a Game, Food, or any other party supply. These objects all implement a common interface, even though the implementations will likely be different for each type of object. Similarly, all activities will implement the perform method. Without knowing the internals of Activity#perform, we can safely assume that the perform method for the Activity object for singing happy birthday will likely have different side effects than the one for playing games. All of these sections of the algorithm have been delegated to the parts of the Party object that are involved in their execution.

The strategy pattern solves the same problem that the template method pattern solves, but it reduces the amount of coupling between objects by using composition over inheritance. Instead of identifying the sections of your algorithm that can vary and then placing those sections in subclasses of an abstract superclass, the algorithm has been delegated to the different parts that compose your object, and those objects implement their respective portions of the algorithm however they see fit.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store