The Structure of Patterns
This post is a cross-post from www.ModernesCpp.com.
The classics "Design Patterns: Elements of Reusable Object-Oriented Software", and "Pattern-Oriented Software Architecture, Volume 1" use similar steps to present their pattern. Today, I will present this structure of a pattern.
Before I write about the structure of a pattern, let me bring you on the same page and start with the definition of a pattern according to Christopher Alexander.
This means that a pattern describes a generic solution to a design problem that recurs in a particular context.
Christopher Alexander uses the three adjectives useful, usable and used to describe the benefits of patterns.
Now, let me write about the structure of a pattern.
Structure of a Pattern
Honestly, there is a strange phenomenon. On the one hand, both books "Design Patterns: Elements of Reusable Object-Oriented Software" and "Pattern-Oriented Software Architecture, Volume 1"?are the most influential books ever written about software development. On the other hand, both books have a great fall-asleep factor. This fall asleep factor is mainly due to the fact that both books present their patterns in?monotonously repeating 13 steps.
In order to bore you not to death, I present these 13 steps in a concise way by applying the "Design Patterns: Elements of Reusable Object-Oriented Software"?structure to the strategy pattern. The intention of each step is displayed in italic. The non-italic contents refer to the strategy pattern.
Name
A concise name that is easy to remember.
Strategy pattern
Intent
An answer to the question: What is the purpose of the pattern?
Define a family of algorithms, encapsulate them in objects, and make them interchangeable at the run time of your program.
Also known as
Alternative names for the pattern if known.
Policy
Motivation
A motivational example for the pattern.
A container of strings can be sorted in various ways. You can sort them lexicographically, case-insensitive, reverse, based on the length of the string, based on the first n characters ... . Hard coding your sorting criteria into your sorting algorithm would be a maintenance nightmare. Consequentially, you make your sorting criteria an object that encapsulates the sorting criteria and configures your sorting algorithm with it.
Applicability
Situations in which you can apply the pattern.
The strategy pattern is applicable when
Structure
A graphical representation of the pattern.
Participants
Classes and objects that participate in this pattern.
Collaboration
Collaboration with the participants.
The context and the concrete strategy implement the chosen algorithm. The context forward client request to the used concrete strategy.
Consequences
What are the pros and cons of the pattern?
The benefits of the strategy pattern are:
Implementation
Implementation techniques of the pattern.
Sample Code
Code snippets illustrating the implementation of the pattern. This book uses Smalltalk and C++.
The strategy pattern is so baked in the design of the Standard Template Library that we may not see it. Additionally, the STL often uses lightweight variants of the strategy pattern.
Here are two of many examples:
STL Algorithms
std::sort can be parametrized with a sorting criterion. The sorting criteria must be a binary predicate. Lambdas are perfect fits for such binary predicates:
// strategySorting.cpp
#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
void showMe(const std::vector<std::string>& myVec) {
for (const auto& v: myVec) std::cout << v << " ";
std::cout << "\n\n";
}
int main(){
std::cout << '\n';
// initializing with a initializer lists
std::vector<std::string> myStrVec = {"Only", "for", "Testing", "Purpose", "!!!!!"};
showMe(myStrVec); // Only for Testing Purpose !!!!!
// lexicographic sorting
std::sort(myStrVec.begin(), myStrVec.end());
showMe(myStrVec); // !!!!! Only Purpose Testing for
// case insensitive first character
std::sort(myStrVec.begin(), myStrVec.end(),
[](const std::string& f, const std::string& s){ return std::tolower(f[0]) < std::tolower(s[0]); });
showMe(myStrVec); // !!!!! for Only Purpose Testing
// sorting ascending based on the length of the strings
std::sort(myStrVec.begin(), myStrVec.end(),
[](const std::string& f, const std::string& s){ return f.length() < s.length(); });
showMe(myStrVec); // for Only !!!!! Purpose Testing
// reverse
std::sort(myStrVec.begin(), myStrVec.end(), std::greater<std::string>() );
showMe(myStrVec); // for Testing Purpose Only !!!!!
std::cout << "\n\n";
}
?
The program strategySorting.cpp sorts the vector lexicographically, case-insensitive, ascending based on the length of the strings, and in reverse order. For the reverse sorting, I use the predefined function object std::greater. The output of the program is directly displayed in the source code.
STL Containers
A policy is a generic function or class whose behavior can be configured. Typically, there are default values for the policy parameters. std::vector and std::unordered_map exemplifies these policies in C++. Of course, a policy is a strategy configured at compile time on template parameters.
template<class T, class Allocator = std::allocator<T>> // (1)
class vector;
template<class Key,
class T,
class Hash = std::hash<Key>, // (3)
class KeyEqual = std::equal_to<Key>, // (4)
class allocator = std::allocator<std::pair<const Key, T>> // (2)
class unordered_map;
?
This means each container has a default allocator for its elements, depending on T (line 1) or on std::pair<const Key, T> (line 2). Additionally, std::unorderd_map has a default hash function (line 3) and a default equal function (4). The hash function calculates the hash value based on the key, and the equal function deals with collisions in the buckets.
Known uses
At least two examples of known use of the pattern.
There are way more use cases of strategies in modern C++.
template< class ExecutionPolicy, class RandomIt >
void sort( ExecutionPolicy&& policy,
RandomIt first, RandomIt last );
?
Thanks to the execution policy, you can sort sequentially (std::execution::seq), parallel (std::execution::par), or parallel and vectorized (std::execution::par_unseq).
Related Patterns
Patterns that are closely related to this pattern.
Strategy objects should be lightweight objects. Consequentially, lambda expressions are an ideal fit.
What's next?
You may wonder, what is the difference between a pattern, an algorithm, or a framework? Let me clarify this in my next post and introduce terms such as pattern sequences and pattern languages.
?
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, Marko, G Prvulovic, Reinhold Dr?ge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, Louis St-Amour, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Neil Wang, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschl?ger, Alessandro Pezzato, Evangelos Denaxas, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Ralf Holly, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, and Stephen Totten.
Thanks in particular to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, Ralf Abramowitsch, John Nebel, Mipko, and Alicja Kaminska.
My special thanks to Embarcadero
My special thanks to PVS-Studio
?
Mentoring Program in English
Do you want to stay informed about my mentoring programs? Write to [email protected].
Seminars
I'm happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
Bookable (Online)
German
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
New
Contact Me