Strategy Design Pattern

Strategy Design Pattern


  • Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
  • This pattern groups algorithms & encapsulates them inside classes that have a common parent so that the algorithm can be changed depending on the requirement.

Strategies are useful when you need to decide at runtime which algorithms to use

Strategies has three main components

  Strategy – the common abstract interface of all the algorithms

  ConcreteStrategy – implementation of strategy

  Context – this object ties the strategy with the main application flow


#include<iostream>

#include<time.h>


using namespace std;


class SortImpl {

public:

   virtual void sort( int[], int ) = 0;

};




class SortBubble : public SortImpl {

public:

   void sort( int v[], int n ) {

      for (int i=n-1; i > 0; --i)

         for (int j=0; j < i; ++j)

            if (v[j] > v[j+1]) {

               int t = v[j];

               v[j] = v[j+1];

               v[j+1] = t;

            }

      cout << "Bubble: ";

      for (int k=0; k < n; k++)

         cout << v[k] << ' ';

      cout << '\n';

   }

};


class SortShell : public SortImpl {

public:

   void sort( int v[], int n ) {

      for (int g = n/2; g > 0; g /= 2)

         for (int i = g; i < n; ++i)

            for (int j = i-g; j >= 0; j -= g)

               if (v[j] > v[j+g]) {

                  int temp = v[j];

                  v[j] = v[j+g];

                  v[j+g] = temp;

               }

      cout << "Shell:  ";

      for (int k=0; k < n; k++)

         cout << v[k] << ' ';

      cout << '\n';

   }

};


class Stat {

public:

   Stat() {

      m_impl = new SortBubble;

   }

   void upGrade() {

      delete m_impl;

      m_impl = new SortShell;

   }

   void downGrade() {

      delete m_impl;

      m_impl = new SortBubble;

   }

   void readVector( int v[], int n ) {

      m_impl->sort( v, n );

      m_min = v[0];

      m_max = v[n-1];

      m_median = v[n/2];

   }


   int getMin()    { return m_min; }

   int getMax()    { return m_max; }

   int getMedian() { return m_median; }


private:

   SortImpl*  m_impl;

   int m_min, m_max, m_median;


};


int main( void ) {

   const int NUM = 9;

   int       array1[NUM], array2[NUM];

   srand( time(0) );

   cout << "Vector: ";


   for (int i=0; i < NUM; ++i) {

      array1[i] = array2[i] = rand() % 9 + 1;

      cout << array1[i] << ' '; }

   cout << '\n';


   Stat  obj;

   obj.upGrade();

   obj.readVector( array1, NUM );

   cout << "min is " << obj.getMin() << ", max is " << obj.getMax()

        << ", median is " << obj.getMedian() << '\n';

   obj.downGrade();

   obj.readVector( array2, NUM );

   cout << "min is " << obj.getMin() << ", max is " << obj.getMax()

        << ", median is " << obj.getMedian() << '\n';

}




When to use this pattern :

Different related classes differ only in their behavior and you want to configure an application with one of many behaviors.

You need different variants of an algorithm.

A class defines many behaviours and these appear as multiple conditional statements in its operations.

Instead of many conditionals, move related conditional branches into their own strategy class.

Setup VSCode with Salesforce

Step by Step guide to setup VSCode with Salesforce Install vscode Install Salesforce CLI (developer.salesforce.com/tools/sfdxcli) Perform fo...