Design Patterns - The Strategy PatternPractical Design Patterns - Strategy Pattern | | This is the third article in a series of articles on Design Patterns. The last article was on the Facade Pattern.
Many times we may be using Design Patterns without knowing that we are using a pattern and certainly without knowing what the particular pattern is called. This was the case for me five or six years ago when I wrote NetRefactor. In that add-in, I had to process both C# and VB.NET code. Since I needed to perform the same function on the two different types of code, I wrote an Interface with numerous methods in it and then wrote a very large file with the classes for both sets of methods in the same file. Admittedly, I had never studied Design Patterns and therefore did not know that I was actually using a Strategy Pattern. But, the point is that the Strategy Design Pattern can be implemented with an interface and I basically was using the pattern in a not quite so clean way, and I did not know that it was a Design Pattern.
The objective of the Strategy Design Pattern is to define a set of algorithms, encapusulate the algorithms into concrete classes of methods, and make them interchangeable to the user of the classes. This decouples the user completely from the implementation of the classes. The Strategy Design Pattern can be implemented more than one way. It can be done with a Interface or an abstract (MustInherit in VB.NET) class. In this article I am going to use an abstract class. The UML diagram shown below shows the components involved in the pattern.

Now I will show the following components in code. First, I will define them.
- Strategy Class - Defines an interface, in the form of an abstract class, that will be implemented by both of the concrete classes.
- Concrete Classes (Strategies) - Implements the code for performing the process of ExtractMethod algorithm.
- Context Class - Contains an instance of the Strategy Concrete Classes and defines the method that allows the caller to access the concrete classes.
Now for the code of the various classes.
/// <summary>
/// The Strategy abstract class.
/// which is an alternate way of creating an interface.
/// </summary>
abstract class ExtractMethodStrategy
{
public abstract void ExtractMethod(string codeToExtract);
} // class
/// <summary>
/// This is the concrete class (where the work is done)
/// for the VB Code.
/// </summary>
class VBMethods : ExtractMethodStrategy
{
public override void ExtractMethod(string codeToExtract)
{
throw new NotImplementedException();
}
} // class
/// <summary>
/// This is the concrete class for processing C# code.
/// </summary>
class CSMethods : ExtractMethodStrategy
{
public override void ExtractMethod(string codeToExtract)
{
throw new NotImplementedException();
}
} // class
/// <summary>
/// This is the context class.
/// </summary>
class LanguageProcessor
{
private ExtractMethodStrategy emStrategy;
private string textToExtract;
/// <summary>
/// Maintain an instance of the concrete processing class.
/// </summary>
/// <param name="ems"></param>
public void SetLanguageProcessingObject(ExtractMethodStrategy ems)
{
emStrategy = ems;
} // method: SetLanguageProcessingObject
/// <summary>
/// Call the concrete object passed to the constructor.
/// </summary>
/// <param name="text"></param>
public void CallExtractMethod(string text)
{
emStrategy.ExtractMethod(text);
} // method: CallExtractMethod
} // class
| My last piece of code is the client calling method that will utilize one of the concrete classes. The one used will be determined by whether we are processing VB.NET or C# code.
/// <summary>
/// Main app class.
/// </summary>
public class MyApplication
{
// the GetCodeType and GetCode methods are not shown
// as they are not germaine to this article.
public void Main()
{
string code;
string codeType;
LanguageProcessor lp = new LanguageProcessor();
code = GetCode();
codeType=GetCodeType();
// instantiate the desired concrete class based on code type
if (codeType.Equals("VB"))
lp.SetLanguageProcessingObject(new VBMethods());
else
lp.SetLanguageProcessingObject(new CSMethods());
} // method: Main
} // class
|
Have you tried our newest product, Visual Class Organizer? You'll be amazed how easy it is to keep the code in your code windows organized. TRY IT FREE FOR 30 DAYS BY CLICKING HERE.
If you are developing in C# and haven't tried CSharpCompleter, you are wasting valuable time typing hundreds of braces {} daily needlessly. Try CSharpCompleter for 30 DAYS FREE.
| Ask a Question, or give your feedback on my articles or products by going to the KnowDotNet Forum or by clicking on My Blog. |  |
You can also email me directly at les@KnowDotNet.com.
|