Congratulations to all the winners of April 2013, they have won INR 3400 cash and INR 20147 worth prizes !
DotNetFunda.Com Logo
Twitter TwitterLinkedIn
YouTubeGoogle
 Online : 8373 |  Welcome, Guest!   Register  Login
 Home > Blogs > Pattern and Practices > An Introduction to Replacement Design Pattern ...
Niladri.Biswas

An Introduction to Replacement Design Pattern

 Blog author: Niladri.Biswas | Posted on: 5/1/2012 | Category: Pattern and Practices Blogs | Views: 665 | Status: [Member] | Points: 75 | Alert Moderator     Download source file


Introduction

Sometimes we come across situations where the problem comes under 2^n problem category type. for example, say we have a checkbox. Now it has barely two states viz.ON/OFF (I am ignoring the tri-state condition). So for a single checkbox, the value is 2^1 = 2. Likely, for two checkbox, the total combination that will appear will be 2^2 = 4. For three checkbox, it will be 2^3 = 8. And so on.

Now writing a program for these kind of situation is really tedious as describe under(pseudo code)

Case 1: For input = 1
IF CHECKBOX1.CHECK = TRUE THEN 1 
ELSE 0
Case 2: For input = 2
IF CHECKBOX1.CHECK = TRUE THEN 1 
ELSE 0
IF CHECKBOX2.CHECK = TRUE THEN 1
ELSE 0
IF CHECKBOX1.CHECK = TRUE AND CHECKBOX2.CHECK = TRUE THEN 1
ELSE 0
IF CHECKBOX1.CHECK = FALSE AND CHECKBOX2.CHECK = FALSE THEN 1
ELSE 0

...and so on. Now try the same for input = 3,4,5,etc. and we will come to know the dificulty of writing such a program and maintainability of the same.

To ease this kind of situation, the Replacement Design Pattern has come into picture

How it works?

In the case of Replacement DP, it initially constructs the entire string and then depending on the value (ON/OFF), it replaces the string.

e.g. with 3 inputs

Step 1: Intial string

 string initialString = Checkbox1.Value + Checkbox2.Value + Checkbox3.value 

Step 2: Replace the string based on the value supplied(ON/OFF)

Suppose for Checkbox1, value is ON

For Checkbox2, value is OFF

For Checkbox3, value is ON

 //Build Checkbox1 option           
initialString = Checkbox1.Check
? ReplaceAll(initialString, Checkbox1.Value, Checkbox1.Value)
: ReplaceAll(initialString, Checkbox1.Value , string.Empty);
//Build Checkbox2 option
initialString = Checkbox2.Check
? ReplaceAll(initialString, Checkbox2.Value, Checkbox2.Value)
: ReplaceAll(initialString, Checkbox2.Value , string.Empty);
//Build Checkbox1 option
initialString = Checkbox3.Check
? ReplaceAll(initialString, Checkbox3.Value, Checkbox3.Value)
: ReplaceAll(initialString, Checkbox3.Value , string.Empty);

The helper function "ReplaceAll" will just do a simple replacement

private static string ReplaceAll(string expression, string oldValue, string newValue)
{
return expression.Replace(oldValue, newValue);
}

So the final output will be

Checkbox1.Value + Checkbox3.value

A concrete example

Consider the below input

What we have to do is that, depending on the country chosen, the output needs to be displayed

So let us first construct a constant class as under

public class Constants
{
public const string INDIA = "India";
public const string USA = "USA";
public const string SWEDEN = "Sweden";
public const string SPAIN = "Spain";
public const string SRILANKA = "Srilanka";
public const string BURMA = "Burma";
public const string CHINA = "China";
public const string NORWAY = "Norway";

public const string TRUE = "=True";
}

Next, let us make a country entity

public class CountryEntity
{
public bool IsIndia { get; set; }
public bool IsUSA { get; set; }
public bool IsSweden { get; set; }
public bool IsSpain { get; set; }
public bool IsSrilanka { get; set; }
public bool IsBurma { get; set; }
public bool IsChina { get; set; }
public bool IsNorway { get; set; }
}

Next let us make the interface "IReplacementDP" which will have "Replace" method expose

 public interface IReplacementDP
{
string Replace(object obj);
}

The concrete class that will implement the "IReplacementDP" will be as under

public class ReplacementDP : IReplacementDP
{
public string Replace(object obj)
{
var objCountryEntity = obj as CountryEntity;

//Create the Display Option Structure
string DisplayOptionStructure =
Constants.INDIA + ";" +
Constants.USA + ";" +
Constants.SWEDEN + ";" +
Constants.SPAIN + ";" +
Constants.SRILANKA + ";" +
Constants.BURMA + ";" +
Constants.CHINA + ";" +
Constants.NORWAY + ";";

//Build India option
DisplayOptionStructure = objCountryEntity.IsIndia
? ReplaceAll(DisplayOptionStructure, Constants.INDIA, Constants.INDIA + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.INDIA + ";", string.Empty);

//Build USA option
DisplayOptionStructure = objCountryEntity.IsUSA
? ReplaceAll(DisplayOptionStructure, Constants.USA, Constants.USA + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.USA + ";", string.Empty);

//Build Sweden option
DisplayOptionStructure = objCountryEntity.IsSweden
? ReplaceAll(DisplayOptionStructure, Constants.SWEDEN, Constants.SWEDEN + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.SWEDEN + ";", string.Empty);

//Build Spain option
DisplayOptionStructure = objCountryEntity.IsSpain
? ReplaceAll(DisplayOptionStructure, Constants.SPAIN, Constants.SPAIN + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.SPAIN + ";", string.Empty);

//Build Srilanka option
DisplayOptionStructure = objCountryEntity.IsSrilanka
? ReplaceAll(DisplayOptionStructure, Constants.SRILANKA, Constants.SRILANKA + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.SRILANKA + ";", string.Empty);

//Build Burma option
DisplayOptionStructure = objCountryEntity.IsBurma
? ReplaceAll(DisplayOptionStructure, Constants.BURMA, Constants.BURMA + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.BURMA + ";", string.Empty);

//Build China option
DisplayOptionStructure = objCountryEntity.IsChina
? ReplaceAll(DisplayOptionStructure, Constants.CHINA, Constants.CHINA + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.CHINA + ";", string.Empty);

//Build Norway option
DisplayOptionStructure = objCountryEntity.IsNorway
? ReplaceAll(DisplayOptionStructure, Constants.NORWAY, Constants.NORWAY + Constants.TRUE)
: ReplaceAll(DisplayOptionStructure, Constants.NORWAY + ";", string.Empty);

return FormatExpression(DisplayOptionStructure, ";");
}

#region Helper Methods

private string ReplaceAll(string expression, string oldValue, string newValue)
{
return expression.Replace(oldValue, newValue);
}

private string FormatExpression(string expression, string delimeter)
{
return
expression.Length > 0
? expression.Substring(0, expression.Length-1)
: expression;
}

#endregion
}

Finally, the client that will invoke will be as under

private void button1_Click(object sender, RoutedEventArgs e)
{
IReplacementDP ireplacementDP = new ReplacementDP();
Func result = x => ireplacementDP.Replace(x);
MessageBox.Show(result(SetRequest()));
}

private CountryEntity SetRequest()
{
return new CountryEntity
{
IsIndia = chkIndia.IsChecked.Value
, IsBurma = chkBurma .IsChecked.Value
, IsChina = chkChina.IsChecked.Value
, IsNorway =chkNorway.IsChecked.Value
, IsSrilanka =chkSrilanka.IsChecked.Value
, IsSpain = chkSpain.IsChecked.Value
, IsSweden =chkSweden.IsChecked.Value
, IsUSA =chkUSA.IsChecked.Value
};
}

The class diagram is as under

Conclusion

The term has been coined by myself and this pattern got evolved as a part of my project. So I thought of sharing the same here.I hope while dealing with 2^n problem, this DP will help us in developing the code as well as maintenance. Hope the article will be useful.Source code is attached herewith.




Best Regards,
Niladri Biswas
Found interesting? Add this to:


Experience:6 year(s)
Home page:http://www.dotnetfunda.com
Member since:Monday, October 25, 2010
Level:Diamond
Status: [Member]
Biography:Lead Engineer at HCL Technologies Ltd., having 6 years of experience in IT field.
I love to explore new technologies and love challenges and try to help others as much as possible not only by coding but also by all possible means.
>> Write Response - Respond to this post and get points

More Blogs

About Us | Contact Us | The Team | Advertise | Software Development | Write for us | Testimonials | Privacy Policy | Terms of Use | Link Exchange | Members | Go Top
General Notice: If you find plagiarised (copied) contents on this page, please let us know the original source along with your correct email id (to communicate) for further action.
Copyright © DotNetFunda.Com. All Rights Reserved. Copying or mimicking the site design and layout is prohibited. Logos, company names used here if any are only for reference purposes and they may be respective owner's right or trademarks. | 5/19/2013 9:50:27 AM