Skip to content

Strategy

A strategy is a design pattern that tells you about different ways to do the same activity. We want to select this action at runtime. Since we have different ways of performing a certain operation, we can talk about a group of algorithms that we want to use interchangeably (depending on the application configuration or user choice).

Design

In order to use the Strategy pattern, we need to define the following:

  • common interface for a group of algorithms performing a certain operation
  • several implementations of the above interface, i.e. a group of common algorithms
  • a class that will choose an appropriate strategy based on the context (i.e. configuration or other external factors)

strategy

Example

The example consists of the following parts:

  • interface SpacesModificationStrategy, which is the common part for a group of algorithms that allows to modify spaces in the input text.
  • three interface implementations of SpacesModificationStrategy:
    • DoubleSpacesStrategy - replaces each space with two
    • RemoveSpacesStrategy - removes any space
    • ReplaceWithUnderscoreStrategy - replaces any space with a _ character
  • SpacesModificationStrategyProvider - allows you to choose the right strategy based on the type
  • sample use of the pattern
class SpacesModificationStrategy:
    def modify(self, inp):
        pass
class DoubleSpacesStrategy(SpacesModificationStrategy):
    def modify(self, inp):
        return inp.replace(' ', '  ')
class RemoveSpacesStrategy(SpacesModificationStrategy):
    def modify(self, inp):
        return inp.replace(' ', '')
class ReplaceWithUnderscoreStrategy(SpacesModificationStrategy):
    def modify(self, inp):
        return inp.replace(' ', '_')
class SpaceModificationStrategyProvider:
    def get(self, strategy_type):
        if strategy_type == 'DOUBLE':
            return DoubleSpacesStrategy()
        elif strategy_type == 'REMOVE':
            return RemoveSpacesStrategy()
        elif strategy_type == 'REPLACE':
            return ReplaceWithUnderscoreStrategy()
def main():
    strategy_type = input("Choose a strategy [DOUBLE|REMOVE|REPLACE]: ")
    inp = "hello from SDA knowledge base!"

    strategy = SpaceModificationStrategyProvider().get(strategy_type)
    output = strategy.modify(inp)

    print(output)


if __name__ == '__main__':
    main()

In conclusion, the strategy is worth using if you prefer composition over inheritance. Additionally, the common interface hides some implementation details, but ultimately the end user must be aware that there are different strategies and some differences.