Skip to main content

Design Patterns: Strategy

The Strategy Pattern is a behavioral design pattern that defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern allows the algorithm to be selected at runtime, providing flexibility in designing software. It’s particularly useful when you have multiple ways of performing a task, and you want to choose the implementation dynamically without altering the client code.


When To Use It?

  • You Have Multiple Algorithms or Behaviors. Use it when you have a need for muplitple ways of performing a task, and you want to make these implementations interchangeable. Examples: Different sorting algorithms, payment methods, discount calculations...
  • You Want to Eliminate Conditional Logic. If you find yourself writing large if-else or switch statements to decide which algorithm to use, this pattern can simplify and clean up your code. Examples: A game character with different attack styles 
  • You Need Runtime Flexibility. Use this pattern if the choice of algorithm or behavior needs to be decided dynamically at runtime rather than compile-time. Example: A game character that changes its movement strategy based on terrain type.

When Not To Use It?

  • The Behavior is Unlikely to Change. If the behavior or algorithm is stable and unlikely to require changes, introducing the this pattern may add unnecessary complexity. Example: A basic calculator where operations (add, subtract) are fixed.
  • You Don't Need Runtime Flexibility. If the algorithm is chosen at compile-time or hardcoded, the strategy pattern is overkill.
  • Strategies Require Too Much Shared State. If the strategies rely heavily on the internal state of the context class, they can become tightly coupled, defeating the purpose of the pattern.

Key Components

  • Strategy Interface: Defines a common interface for all the algorithms (strategies).
  • Concrete Strategies: Implement different versions of the algorithm defined in the strategy interface.
  • Context: Maintains a reference to a Strategy object and delegates the work to the strategy.

Example in C#

Interface
public interface IMoveStrategy
{
    void Move();
}
Concrete Strategies
public class Crouch : IMoveStrategy
{
    public void Move()
    {
        Console.WriteLine("Character is crouching slowly...");
    }
}

public class Walk : IMoveStrategy
{
    public void Move()
    {
        Console.WriteLine("Character is walking at a normal pace...");
    }
}

public class Run : IMoveStrategy
{
    public void Move()
    {
        Console.WriteLine("Character is running fast...");
    }
}

Context
public class CharacterContext
{
    private IMoveStrategy _moveStrategy;

    public CharacterContext(IMoveStrategy moveStrategy)
    {
        _moveStrategy = moveStrategy;
    }

    public void SetMovementStrategy(IMoveStrategy moveStrategy)
    {
        _moveStrategy = moveStrategy;
    }

    public void ExecuteMove()
    {
        _moveStrategy.Move();
    }
}

Client
using System;

class Program
{
    static void Main(string[] args)
    {
        // Create a character with an initial movement strategy (Walk)
        CharacterContext character = new CharacterContext(new Walk());

        while (true)
        {
            Console.WriteLine("\nChoose movement: crouch, walk, run, or exit.");
            string input = Console.ReadLine()?.ToLower();

            if (input == "exit")
                break;

            // Manually select the strategy based on user input
            IMoveStrategy selectedStrategy = input switch
            {
                "crouch" => new Crouch(),
                "walk" => new Walk(),
                "run" => new Run(),
                _ => null
            };

            if (selectedStrategy != null)
            {
                character.SetMovementStrategy(selectedStrategy);
                character.ExecuteMove();
            }
            else
            {
                Console.WriteLine("Invalid input! Please enter crouch, walk, or run.");
            }
        }
    }
}

Conclusion

The Strategy Pattern provides flexibility, scalability, and cleaner code, making it a great choice for scenarios like game character movement, AI behavior, and dynamic algorithm selection.

Comments

Popular posts from this blog

Design Patterns: Singleton

Tyipically the first design pattern most people learn, often wrongly ☺ To give an introduction, we can say that singleton is one of the creational design patterns which ensures only one class instance with single point of access thru entire application.  Because it is relatively simple to implement, the Singleton pattern is sometimes misapplied in situations where it is not the most suitable choice. When to use it? Here are the few examples of corrent usage of singleton: Configuration Management  Centralized configuration settings for consistent use thru entire application Caching Maintaning  Single istance of cached objects for easy and fast acces Logging  Ensure unified mechanism to avoid duplication of log files, formats, etc Global State Management  Centralized management of the state which is needed to be shared accross the application Resource sharing  Thread pools, database connection, I/O operations When not to use it? On the other hand, here are fe...

Design Patterns: Builder

This is also, like a Singleton , one of the creational design patterns. It provides the way of creating complex objects step by step by simple chaining and every particular step is independent of other steps. Let us dive into the real example of usage. For showing purpose we have created an example in C# which creates simple SQL queries using described pattern.  using System; using System.Text; namespace BuilderPatternExample { public interface ISqlQueryBuilder { ISqlQueryBuilder Select(string columns); ISqlQueryBuilder From(string table); ISqlQueryBuilder Where(string condition); ISqlQueryBuilder OrderBy(string columns); string Build(); } public class SelectQueryBuilder : ISqlQueryBuilder { private readonly StringBuilder _queryBuilder; public SelectQueryBuilder() { _queryBuilder = new StringBuilder(); } public ISqlQueryBuilder Select(string columns) { ...

Why Do Employers Lie In Interviews?

This is a very common subject that many of us have already experienced. But when you realize that half of what has been said at interviews is actually a lie, you are already at least six months in the company, you have already started some project and it wouldn’t be appropriate to leave the company at that moment. Why is this happening? First of all, let us see how the usual interview process looks like in software development companies. First round interview in most of these companies is an interview with HR. This is the first insight about the company. A person who works in HR is usually someone who, in most cases, doesn’t understand what the software is and how the software development process goes. Big respect to those companies where HR knows these things. This phase usually contains some standard questions about your personality, what do you like about the company, how this company is something that you are actually looking for, where you see yourself in five/ten  years etc… ...