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)
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 twoRemoveSpacesStrategy
- removes any spaceReplaceWithUnderscoreStrategy
- 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.