Robert Larson

  • Home
  • About Me
  • Contact Me
  • Product Recommendations
  • Client Portal

The Strategy Pattern using C++ (The Force is Strong with this Pattern)

The Strategy Pattern using C++ (The Force is Strong with this Pattern)

January 27, 2017 by Robert Larson

One of the design patterns I have used often in my career is the Strategy Pattern. This is a very powerful pattern. I like the definition from my favorite patterns book, “Head First Design Patterns: A Brain-Friendly Guide“

The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

I wrote up an example using C++ that I’d like to share to help show what the Strategy Pattern is all about. I have decided to take three of our favorite Star Wars characters, Han Solo, Luke Skywalker and Chewy. Each one of them has their own weapon of choice. Han likes to use his Blaster, Luke, of course, uses a light saber and Chewy uses a crossbow. Can you see what might be the family of algorithms (or set of behaviors) from this description? If you chose the use of weapons, the force is strong with you! Well done!

So let’s create our interface to the algorithms and call it WeaponBehavior which has an abstract method useWeapon().


class WeaponBehavior { public: virtual ~WeaponBehavior() {} virtual void useWeapon() = 0; };

The three weapon behaviors would implement this interface. Let’s name them BlasterBehavior, LightSaberBehavior and CrossBowBehavior.


class BlasterBehavior: public WeaponBehavior { public: BlasterBehavior(); virtual ~BlasterBehavior(); virtual void useWeapon() { std::cout << "I am using my blaster!\n"; } }; class LightSaberBehavior: public WeaponBehavior { public: LightSaberBehavior(); virtual ~LightSaberBehavior(); virtual void useWeapon() { std::cout << "I am using my light saber!\n"; } }; class CrossBowBehavior: public WeaponBehavior { public: CrossBowBehavior(); virtual ~CrossBowBehavior(); virtual void useWeapon() { std::cout << "I am using my cross bow!\n"; } };

So what clients would make use of our WeaponBehaviors? Our Star Wars characters, of course! I created a class called StarWarsCharacter that implements a Fight() method that delegates the behavior to its WeaponBehavior member that is initialized by a parameter passed into the constructor. It also has a string member for the name of the character that is also initialized with a parameter passed into the constructor. We have a SetWeaponBehavior() method to allow changing our character’s WeaponBehavior dynamically. Doing so demonstrates the flexibility of the Strategy Pattern and its interchangeability of its behavior without changing the StartWarsCharacter implementation. The relationship between the StarWarsCharacter class and the WeaponBehavior interface is one of composition. In other words, the StarWarsCharacter is being composed with the right WeaponBehavior object. This is a good example of using the design principle to favor composition over inheritance.


#include class WeaponBehavior; class StarWarsCharacter { public: StarWarsCharacter(std::string name, WeaponBehavior * weaponBehavior); virtual ~StarWarsCharacter(); virtual void Fight(); virtual void SetWeaponBehavior(WeaponBehavior * weaponBehavior) { m_pWeaponBehavior = weaponBehavior; } protected: WeaponBehavior * m_pWeaponBehavior; std::string m_name; };

Ok, so now we have our classes defined. Let’s write a program to put them to use. Below we start with creating our three different WeaponBehaviors. Next create our three StarWarsCharacters and pass the preferred WeaponBehavior in the constructors as well as the name of the character. Now we can demonstrate the the use of these WeaponBehaviors for each character by calling the Fight() method (which just prints the behavior being used). After that, lets demonstrate the change of the behavior at runtime by changing the WeaponBehavior for each character and then calling Fight() again to show they now have different WeaponBehaviors.


#include #include "BlasterBehavior.h" #include "CrossBowBehavior.h" #include "LightSaberBehavior.h" #include "StarWarsCharacter.h" int main() { WeaponBehavior * blasterBehavior = new BlasterBehavior(); WeaponBehavior * lightSaberBehavior = new LightSaberBehavior(); WeaponBehavior * crossBowBehavior = new CrossBowBehavior(); StarWarsCharacter * hanSolo = new StarWarsCharacter(std::string("Han Solo"), blasterBehavior); StarWarsCharacter * lukeSkywalker = new StarWarsCharacter(std::string("Luke Skywalker"), lightSaberBehavior); StarWarsCharacter * chewy = new StarWarsCharacter(std::string("Chewy"), crossBowBehavior); hanSolo->Fight(); lukeSkywalker->Fight(); chewy->Fight(); hanSolo->SetWeaponBehavior(lightSaberBehavior); lukeSkywalker->SetWeaponBehavior(crossBowBehavior); chewy->SetWeaponBehavior(blasterBehavior); hanSolo->Fight(); lukeSkywalker->Fight(); chewy->Fight(); delete hanSolo; delete lukeSkywalker; delete chewy; delete blasterBehavior; delete lightSaberBehavior; delete crossBowBehavior; return 0; }

Here is the output.


Han Solo: I am using my blaster! Luke Skywalker: I am using my light saber! Chewy: I am using my cross bow! Han Solo: I am using my light saber! Luke Skywalker: I am using my cross bow! Chewy: I am using my blaster!

Feel free to download the code here

Well there you have it. I hope you see how powerful this pattern is and how it can be applied. I hope you enjoyed this post. I plan to do more Design Pattern posts in the future, so if you have any requests please let me know or feel free to subscribe.

 

Recommended Resources

Here are some resources I recommend for more information on the Strategy Pattern

Head First Design Patterns: A Brain-Friendly Guide

Design Patterns: Elements of Reusable Object-Oriented Software

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

Posted in: c++, Design Patterns Tagged: c++, designpatterns
← Is a Scrum Master required to attend the daily scrum meeting?
Remembering My First Scrum Team Common Area Experience. →
  • Home
  • About Me
  • Contact Me
  • Product Recommendations
  • Client Portal

Recent Posts

  • March Madness 2019 – Weighted Random Bracket Generator
  • Gifts Ideas for Software Developers 2018-2019
  • March Madness 2018 – Second Chance Weighted Random Bracket Generator
  • March Madness 2018 – Weighted Random Bracket Generator
  • Builder Pattern using C++ (NFL Scheduler Example)

Archives

  • March 2019
  • November 2018
  • March 2018
  • August 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017

Follow me on Twitter

My Tweets

Copyright © 2025 Robert Larson.

Grace WordPress Theme by SiteChurch

%d