Strategy pattern Strategy instance and analysis

The design patterns are all organized from the introductory course of design patterns by Mr. Li Jianzhong

strategy pattern

The strategy pattern is a kind of component collaboration pattern.

1. Definition

Encapsulate a series of algorithms one by one, and they can replace (change) each other. This pattern allows the algorithm to be varied (extended, subclassed) independently of the clients that use it (stable).

Further discussion: The algorithms here are constantly changing in use. By encapsulating different algorithms and inheriting from the same parent class, different algorithms can be called according to needs at runtime instead of all the algorithms at compile time. Algorithms are compiled simultaneously.

2. Motivation

  • In the process of software construction, the algorithms used by some objects may be varied and often changed. If these algorithms are encoded into the object, the object will become extremely complicated; and sometimes supporting unused algorithms is also a performance burden.
  • How can I transparently change an object's algorithm as needed at runtime? Decouple the algorithm from the object itself, thus avoiding the above problems?

3. Examples and Analysis

#include <algorithm>
#include <iostream>

#define free_ptr(p) if(p) delete p; p = nullptr;

//strategy class, which defines the public interface for all supported algorithms
class Strategy 
{
public:
    virtual ~Strategy() {};
    virtual void AlgorithmInterface() = 0;
};

//ConcretStrategy encapsulates a specific algorithm and inherits the child Strategy
class ConcreteStrategyA : public Strategy
{
    void AlgorithmInterface()
    {
        std::cout << "algorithm A accomplish" << std::endl;
    }
};

class ConcreteStrategyB : public Strategy
{
public:
    void AlgorithmInterface()
    {
        std::cout << "algorithm B accomplish" << std::endl;
    }
};

class ConcreteStrategyC : public Strategy
{
public:
    void AlgorithmInterface()
    {
        std::cout << "algorithm C accomplish" << std::endl;
    }
};


//The context is configured with a ConcreteStrategy and maintains a reference to the Strategy
class Context
{
public:
    Context(Strategy* strategy) : m_strategy(strategy) { };
    ~Context() { free_ptr(m_strategy); }
    void AlgorithmInterface()
    {
        m_strategy->AlgorithmInterface();
    }
private:
    Strategy *m_strategy;
};

int main()
{
    Strategy* A = new ConcreteStrategyA();
    Strategy* B = new ConcreteStrategyB();
    Strategy* C = new ConcreteStrategyC();
    A->AlgorithmInterface();
    B->AlgorithmInterface();
    C->AlgorithmInterface();

    free_ptr(A);
    free_ptr(B);
    free_ptr(C);
    return 0;

}

operation result:

algorithm A accomplish
 algorithm B accomplish
 algorithm C accomplish

In this code, since the three algorithms A, B, and C have the same basic structure, in order to reduce the repetition of the code, a base class is set to contain their commonality, and the three algorithms A, B, and C inherit their commonality part and implement the function. Then, when the main function is running, declare the algorithm of the base class, and then only need to call the corresponding subclass according to different needs to realize the corresponding function.

4. Usage scenarios

1. Many related classes simply behave differently. The Strategy pattern provides a way to configure a class with one of several behaviors.
2. Different variants of an algorithm need to be used. For example, you might define algorithms that reflect different space/time tradeoffs. The Strategy pattern can be used when these variants are implemented as a class hierarchy for an algorithm.
3. Algorithms use data that customers should not know. The Strategy pattern can be used to avoid exposing complex, algorithm-dependent data structures.
4. A class defines a variety of behaviors, and these behaviors appear in the form of multiple conditional statements in the operation of this class. Move related conditional branches into their respective Strategy classes in place of these conditional statements.

5. Advantages and disadvantages

Advantages: The strategy mode summarizes the algorithm, making it easier to switch and expand the algorithm.

Disadvantages: Policy users need to understand each specific policy, which makes the encapsulation of the whole model not strong.

6. Summary points

  • The Strategy mode and its subclasses and components provide a series of reusable algorithms, so that the type can be easily switched between each algorithm as needed at runtime.
  • The Strategy pattern provides an alternative to using conditional statements. Eliminating conditional judgment statements is decoupling, and the layout and maintenance costs of multiple conditional judgment statements are relatively high, and the logic is more confusing. Using Strategy mode can effectively avoid this problem.
  • If the Strategy object has no instance object, then the context can share the same Strategy object, thus saving object overhead.

Organized from:
http://mtw.so/5YfjSP
https://github.com/Bigmartin121/C-plusplus-design-patterns-Li/tree/main/Strategy

Tags: C++ Design Pattern

Posted by jackofalltrades on Wed, 07 Dec 2022 05:17:34 +0530