Design Pattern Evangelist Blog

Smart pointers about software design

Specification Design Pattern – Use Case

Using the Specification Design Pattern for Smart Playlists


Smart Playlist

Introduction

Specification Design Pattern introduced the Specification Design Pattern, but it was getting a bit too long. This blog continues the story with a Use Case.

Use Case

Smart Playlists are probably one of the best real world programming examples I can think of for Specification.

Smart Playlist Description

iTunes allows users to create playlists of their favorite music. I think most people curate their playlists manually, which means that if you load a new CD into iTunes and you wanted some of the tracks in your playlist, then you’d need to manually place them there.

There is another type of iTunes playlist, which I prefer even more. It is the Smart Playlist. See How to Create Smart Playlists in Apple Music & iTunes for an article describing Smart Playlists with a few screenshots.

Users can create a named smart playlist and define a set of criteria for the tracks that they want to appear in the playlist. Criteria is based upon the following:

Unlike manual playlists, which are static, smart playlists are dynamic. Anytime a new track is added to iTunes it will automatically be part of a smart playlist for which its attributes match the smart playlist criteria. Likewise, if the user modifies the smart playlist definition, then all tracks in iTunes will automatically adjust to be added, removed, or remain based upon the updated smart playlist criteria.

A Beats Per Minute workout smart playlist could be a common smart playlist. If the user uploads a new pop song with a fast beat, then it will automatically be added to the workout playlist.

I created several smart playlists for my own use in these three basic categories:

The All grouping is a logical AND. The Any grouping is a logical OR.

I don’t know if the smart playlist developers at Apple used Specification for their design, but if I had been assigned the smart playlist design and implementation, I definitely would have considered Specification.

A Smart Playlist Design

The Smart Playlist Design is going to mirror Specification Design so closely, that for the most part, I’m going to focus upon diagrams more than text.

Smart Playlist Design via Strategy

Other than name changes, this is identical to the Specification Strategy Design:

Leaf Playlist Classes

Smart Playlist Design via Composites

Other than name changes, this is identical to the Specification Composite Design, even the implementation details; however the final details are not shown due to space constraints. See Specification Use Case - My Final Comment Or My Comment About Final for those details.

Composite Playlist Classes

Smart Playlist Specification

Let’s say you wanted the following Smart Playlist Specification:

Alternative, Rock, or New Wave 5-star tracks as long as they are not The Rolling Stones or U2.

You’d be able to design this Smart Playlist with this GUI specification: Smart Playlist

The code that might construct this Specification could look something like:

Specification genres = new AnySpecification();
genres.add(new GenreSpecification(Alternative));
genres.add(new GenreSpecification(Rock));
genres.add(new GenreSpecification(NewWave));

Specification acceptedArtists = new AllSpecification();
acceptedArtists.add(new NotSpecification(new ArtistSpecification("The Rolling Stones")));
acceptedArtists.add(new NotSpecification(new ArtistSpecification("U2")));

Specification constraints = new AllSpecification();
constraints.add(new RatingSpecification(5));
constraints.add(acceptedArtists);

Specification fiveStarAltRock = new AllSpecification();
fiveStarAltRock.add(genres);
fiveStarAltRock.add(constraints);

The above is a sample of how to build the Specification/Composite tree statically. However, this would not support the flexible GUI. The software behind the GUI would still call the same methods shown above, but it would do so in a more piecemeal approach were each element would be considered individually, created, and assembled into the whole structure.

The Specification/Composite tree would be: Leaf Playlist Classes

A Redundant All Grouping?

I found the above Smart Playlist example on the internet. I think there’s a redundant All grouping in it. While the redundant All isn’t incorrect, here’s a static implementation that I think satisfies the same tracks:

Specification genres = new AnySpecification();
genres.add(new GenreSpecification(Alternative));
genres.add(new GenreSpecification(Rock));
genres.add(new GenreSpecification(NewWave));

Specification acceptedArtists = new AllSpecification();
acceptedArtists.add(new NotSpecification(new ArtistSpecification("The Rolling Stones")));
acceptedArtists.add(new NotSpecification(new ArtistSpecification("U2")));

Specification fiveStarAltRock = new AllSpecification();
fiveStarAltRock.add(genres);
fiveStarAltRock.add(new RatingSpecification(5));
fiveStarAltRock.add(acceptedArtists);

It’s Specification/Composite tree would be: Leaf Playlist Classes

Summary

This Use Case shows how Specification could be used as the design/implementation mechanism for Smart Playlists. Specification allows a user to create any number of Smart Playlists customized to each user’s specifications.

References

See: Specification Design Pattern/References.

Comments

Previous: Specification Design Pattern

Next: Interpreter Design Pattern - An Introduction

Home: Design Pattern Evangelist Blog