I have read some of the related questions regarding how we can refactor a code based on if/else if
statements to follow closely the OOP
principles but I have difficulties to apply this to a concrete use-case.
I have the following base class:
public class Human
{
public bool IsMother { get; set; }
public bool IsFather { get; set; }
public bool Isdaughter { get; set; }
public bool IsSon { get; set; }
public string WhatAmI { get; set; }
}
and several derived classes:
public class Parent : Human
{
public Parent()
{
WhatAmI = "Parent";
}
}
public class Daughter : Human
{
public Daughter()
{
WhatAmI = "Daughter";
}
}
public class Son : Human
{
public Son()
{
WhatAmI = "Son";
}
}
So based on a several conditions I should return a specific type of Human.
for example if I have this:
var human = new Human();
human.IsFather = false;
human.IsMother = false;
human.IsSon = true;
human.Isdaughter = false;
var newHuman = HumanHelper.GetHuman(human);
Console.WriteLine(newHuman.WhatAmI);
the console output is "Son" which is correct but the implementation of the GetHuman(Human human)
method is bothering me because of the abuse of if-else
statements. And the concrete implementation is this:
public static class HumanHelper
{
private static string kindOfHuman = ConfigurationManager.AppSettings["kindOfHuman"];
public static Human GetGuman(Human human)
{
if (kindOfHuman == "parent")
{
if (human.IsMother || human.IsFather)
{
return new Parent();
}
}
else if (kindOfHuman == "child")
{
if (!human.IsMother && !human.IsFather)
{
if (human.Isdaughter)
{
return new Daughter();
}
else if (human.IsSon)
{
return new Son();
}
}
}
throw new ArgumentException("Should not get here");
}
}
It is difficult to read and I think that I am doing something simple and relatively standard in a non simple and non-standard way. So could you help me with improving this code?
Human
object if you already have aHuman
object? – Winston Ewert Sep 02 '16 at 02:08Human
represents an assembled service request which is being processed by the internal system. At some point I have enough information (which is not available during the assembling of the initial request) to create an object of more specific type. After that I go out of process and the next service needs this new object. Later on, some of the decisions are made based on the specific type of the passed object so I need an exact instance. – Leron Sep 02 '16 at 02:49GetGuman
? Why both the is* methods and kindOfHuman (they seem partially redundant)? – Winston Ewert Sep 02 '16 at 03:33Is*
properties represent exactly the branching of my code. – Leron Sep 02 '16 at 05:29GetHuman()
? It seems to combine boolean flags in the input with a config setting, but what is the actual logic? – JacquesB Sep 02 '16 at 12:11|
bitwise field could be the way to go – askrich Sep 02 '16 at 16:26