Skip to main content

Design Pattern - Strategy


Today out of curiosity, I was experimenting with strategy design pattern.
Here's the outcome of my experiment.

Strategy pattern falls under the Behavioral category.

The Intent:
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 pattern embodies two fundamental principle of object oriented programming. First encapsulate the concept which changes behaviour and program against the interface.

I had written a small notepad application to illustrate the use of strategy.
Other things remaining same, the dynamics of the pattern is applied when using the "find" method in the notepad. Based on the user's selection either a normal "find" alogrithm is invoked or a "regex" based algorithm is used.

The application being trivial, you wont find much regex code. Its used only for demonstration purpose.

Dissecting the application

(1) Program against the interface


// IFind.cs - This would be our strategy interface
using System;
using System.Windows.Forms;
namespace DesignPatterns
{
public interface IFind
{
int Find(RichTextBox textControl,string str);
}
}

// NormalFind.cs - An implementation of 1st algorithm - ConcreteStrategyA
using System;
using System.Windows.Forms;

namespace DesignPatterns
{
public class NormalFind : IFind
{
static int filePointer = 0;
public NormalFind()
{}

int IFind.Find(RichTextBox textControl, string str)
{
int start = -1;
try
{
start = textControl.Text.IndexOf(str, filePointer);
int len = str.Length;

textControl.Select(start, len);
textControl.Focus();
filePointer = start + len;
}
catch (Exception e)
{
e.ToString();
MessageBox.Show("Reached End of Document.");
filePointer = 0;
}
return start;
}
}
}

// RegexFind.cs - An implementation of 2nd algorithm - ConcreteStrategyB
using System;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace DesignPatterns
{
public class RegexFind : IFind
{
static int filePointer = 0;
int start = -1;
public RegexFind()
{}

int IFind.Find(RichTextBox textControl,string str)
{
Regex r = new Regex(str);
try
{
Match m = r.Match(textControl.Text,filePointer, textControl.TextLength);
Trace.Assert(m.Success);
textControl.Select(m.Index, m.Length);
textControl.Focus();
filePointer = m.Index + m.Length;
start = m.Index;
}
catch (Exception e)
{
e.ToString();
MessageBox.Show("Reached End of Document.");
filePointer = 0;
}
return start;
}
}
}

// FindManager.cs - Handles the strategy context -
using System;
using System.Windows.Forms;
namespace DesignPatterns
{
public class FindManager
{
IFind find;
RichTextBox rtb;

public FindManager()
{}

public FindManager(RichTextBox rbox)
{
this.rtb = rbox;
}

public void SetFindStrategy( IFind myfind)
{
this.find =myfind;
}

public int Find(string findString)
{
return find.Find(rtb, findString);
}
}
}

// The client code extract
private void btnFind_Click(object sender, System.EventArgs e)
{
FindManager fm = new FindManager(this.richTextBoxInstance);
// dynamically set the strategy
if (chkRegEx.Checked == true)
fm.SetFindStrategy(new RegexFind());
else
fm.SetFindStrategy(new NormalFind());

fm.Find(txtFind.Text);
}

For more information go to
www.dofactory.com
davidhayden.com/blog
Also refer the GOF pattern book.

UML class diagram has been adapted from www.dofactory.com. I hope they don't mind it.



Enjoy patterning :)

Comments

Anonymous said…
Hi Rajesh,

Read your post.. keep them coming.. but do remember that now u have readers of your blog who are not .net savy as u are... I will have more questions to ask now...

Cheers and happy blogging :D
Chetan
Rajesh Pillai said…
Hi Chetan,
You are always welcome :)
Rajesh

Popular posts from this blog

JavaScript Scope

In this blog post we will dig deeper into various aspects of JavaScript scope.  This is a pretty interesting topic  and also a topic which confuses many beginning JavaScript programmers. Understanding JavaScript scope helps you write bug free programs (hmm.. atleast helps your troubleshoot things easily) Scope control the visibility and lifetimes of variables and parameters.  This is important from the perspective of avoiding naming collisions and provides memory management service. Unlike other languages, JavaScript does not have block level scope.  For e.g. take for instance the following piece of c# code. public void Main () { int a = 5; if (true) { int b = 10; } // This will throw compile time error as b is not defined // and not within the scope of function Main(); Console.WriteLine(b); } If you write the same code in JavaScript, then the value of 'b' will be available outside the 'if' block. The reason for this is JavaScript does no...

Core Leadership Strengths

Here are few notes that I am putting out from my leadership training seminar. Lets have a look at the "Five Clusters of Strength". - Personal Character Character is who you are when no one is looking. This is the core strength which every leader/human should possess. This deals with the ethical standards, integrity and authenticity of the leader. - Personal Capability This trait deals with the intellectual, emotional, and skill of the individual. It includes analytical and problem-solving capabilities along with the technical competencies. Great leaders need a strong collection of these personal capabilities. - Focus on result This deals with capability to achieve results, having an impact on the organization. It also highlights the capability for getting things done. - Interpersonal/People skill This relates with character. It deals with the leaders ability to effectively communicate with the people. Its a direct expression of the character of the individ...

MCPD: Microsoft .NET Framework 2.0—Application Development Foundation[70-536]

Link to online resource which covers most of the aspect of passing this exam can be found at the following URL. http://www.publicjoe.co.uk/536/70-536.html The following points will help you remember some of the important aspect of passing the 70-536 exam.[Application Development Foundation] The StringBuilder[System.Text namespace] class is used for optimized string concatenation. For more detailed information follow the below url http://msdn2.microsoft.com/en-us/library/system.text.stringbuilder(VS.71).aspx PrincipalPermission is used to gain insight into user's credential. For more info refere the following URL. http://msdn2.microsoft.com/en-us/library/system.security.permissions.aspx The SmtpClient class should be used to send e-mail by using the Simple Mail Transfer Protocol[System.Net.Mail]. Attachment content can be a String , Stream , or file name. You can specify the content in an attachment by using any of the Attachment constructors. For more details refer the followin...