I am very new to design pattern. Recently, I learned about the Chain of Responsibility pattern, so I tried to practice it. These nested conditionals are what I'm trying to replace with polymorphism using Chain of Responsibility:
if (gender == 'M')
{
if (age >= 1 && age <= 10){
if (name.Contains("A"))
strInformation = "Male Child, contains 'A'";
else (name.Contains("A") == false)
strInformation = "Male Child, not contains 'A'";
}
else if (age >= 11 && age <= 20) {
if (name.Contains("A"))
strInformation = "Male Teen, contains 'A'";
else (name.Contains("A") == false)
strInformation = "Male Teen, not contains 'A'";
}
}
else if (gender == 'F')
{
if (age >= 1 && age <= 10){
if (name.Contains("A"))
strInformation = "Female Child, contains 'A'";
else if(name.Contains("A") == false)
strInformation = "Female Child, not contains 'A'";
}
else if (age >= 11 && age <= 20) {
if (name.Contains("A"))
strInformation = "Female Teen, contains 'A'";
else (name.Contains("A") == false)
strInformation = "Female Teen, not contains 'A'";
}
}
I know you guys can easily determine what that code is trying to achieve. Next, I'm going to show you my implementations of CoR pattern regarding that.
//This is my main class that handles all the request
public abstract class Handler
{
protected Handler handler;
public void SetNext(Handler _handler){
this.handler = _handler;
}
public virtual string Execute(string name, int age, char gender)
{
if(handler != null) {
return handler.Execute(name, age, gender);
}
return "Not implemented error!!";
}
}
public class Male : Handler
{
public override string Execute(string name, int age, char gender)
{
if (gender == 'M' && age >= 1 && age <= 10) {
handler = new Malechild();
}
else if (gender == 'M' && age >= 11 && age <= 20) {
handler = new MaleTeen();
}
return base.Execute(name, age, gender);
}
}
public class Malechild : Handler
{
public override string Execute(string name, int age, char gender)
{
if(name.Contains("A"))
{
handler = new MaleChildContainsA();
}
else if(name.Contains("A") == false)
{
handler = new MaleChildNotContainsA();
}
return base.Execute(name, age, gender);
}
}
public class MaleChildContainsA : Handler
{
public override string Execute(string name, int age, char gender)
{
return "Male Child, contains 'A'";
}
}
public class MaleChildNotContainsA : Handler
{
public override string Execute(string name, int age, char gender)
{
return "Male Child, NOT contains 'A'";
}
}
And so on!!! I will not put the other code as I think it is prohibited by codereview to put so much code and less explanation and details, just imagine the next step, I also have MaleTeen, MaleTeenContainsA, MaleTeenNotcontainsA classes who do the same as the Male, MaleChildContainsA, and MaleChildNotContainsA classes. Aside from that, I still have classes for Female, I won't just put it. Imagine, how long my code is. It's horrible..
I implemented it on my Main Method like this..
Handler male = new Male();
Handler female = new Female();
male.SetNext(female);
var m = male.Execute(name, age, gender);
Console.WriteLine("Answer: {0}", m);
I've got no error by doing this code, but I know I did it wrong. Maybe I over over-engineered it which is wrong according to many articles that I've read. Now, my question is, how to do it right? If you encounter the same problem as that, what is the right way of doing it? Is it wrong to implement Chain of Responsibility for that problem?
male.Execute
twice, first with a male and then with a female - it'll fail to recognize the female. I think the KISS (Keep It Stupidly Simple) and DRY (Don't Repeat Yourself) patterns are more useful here. ;) \$\endgroup\$