A Strategy pattern is a group of algorithms encapsulated inside classes that are made interchangeable so the algorithm can vary depending on the class used. Strategies are useful when you would like to decide at run time when to implement each algorithm. They can be used to vary each algorithm’s usage by its context.
The Strategy pattern has three main components: the Strategy, the Concrete Strategy, and the Context. The strategy is a common interface that ties together all supported algorithms.
Usually this class is abstract. The concrete strategy is the implementation class where the logic for each different algorithm lives in the group. The context is the object that ties a concrete strategy to a particular code flow.
Strategies are useful when you would like to use a family of algorithms across different contexts. Perhaps you have classes that each contains a different algorithm and you wish to allow them to use a common interface.
Strategies are useful ways to maintain a family of algorithms in such a way that they can easily be called
dynamically and independent of immutable logical code. They allow similar inputs to interact in different ways just by switching the strategy type. Expressions can change by swapping only the strategy, not the inputs, giving flexibility to interfaces that may receive inputs from different sources that need processing in a unified manner.
href="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_filelist.xml" rel="File-List" />
Remember The GoF book says the Strategy design pattern should: “Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.”
The Strategy design pattern points out that, sometimes, it’s good to be task-oriented. That’s especially important if you want to maintain volatile code away from the main code for your app, or if you want to change the algorithm you use at runtime.
Tip Consider using the Strategy design pattern if you have one of the following situations:
· You have volatile code that you can separate out of your application for easy maintenance.
· You want to avoid muddling how you handle a task by having to split implementation code over several inherited classes.
· You want to change the algorithm you use for a task at runtime.