Description
In OOP you will often encounter the abundance of using IF/Else which on the negative side may provide a deep layer of nesting which is increasing the complexity of your solution. Imagine having more then 2 variables that must be tested simultaneously.
There are some good design patterns that would replace the classical procedural approach with a nice smooth OOP approach.
One approach is names Strategy Pattern. Consider objects to the right:
public enum EmployeeType
{
Manager,
Administrative,
General
}
public class Employee
{
public string Name { get; set; }
public EmployeeType Type { get; set; }
}
public class Payments
{
public double Pay(Employee employee)
{
switch (employee.Type)
{
case EmployeeType.Administrative:
return 100;
case EmployeeType.Manager:
return -1000;
case EmployeeType.General:
return 200;
default:
return 0;
}
}
}
static void Main(string[] args)
{
Employee me = new Employee { Name = "Me", Type = EmployeeType.Manager };
Payments payments = new Payments();
Console.WriteLine(payments.Pay(me));
}
Solution
We continue by introducing polymorphism into Employee class. Then instead of determining what type of employee it is, we define separate handlers for each
public abstract class Employee
{
public string Name { get; set; }
public EmployeeType Type { get; protected set; }
}
public class EmployeeAdministrative : Employee
{
public EmployeeAdministrative()
{
this.Type = EmployeeType.Administrative;
}
}
public class EmployeeManager : Employee
{
public EmployeeManager()
{
this.Type = EmployeeType.Manager;
}
}
public class EmployeeGeneral : Employee
{
public EmployeeGeneral()
{
this.Type = EmployeeType.General;
}
}
public class Payments
{
public double Pay(EmployeeAdministrative employee) => 100;
public double Pay(EmployeeManager employee) => -1000;
public double Pay(EmployeeGeneral employee) => 200;
}
static void Main(string[] args)
{
EmployeeManager me = new EmployeeManager { Name = "Me" };
Payments payments = new Payments();
Console.WriteLine(payments.Pay(me));
}
The following introduces a new pattern , strategy pattern, into the overloaded methods will make the code even cleaner:
public class Payments
{
private Dictionary<EmployeeType, Func<double>> paymentType
= new Dictionary<EmployeeType, Func<double>>
{
{ EmployeeType.Manager, () => -1000 },
{ EmployeeType.Administrative, () => 100},
{ EmployeeType.General, () => 200 }
};
public double Pay(Employee employee) => paymentType[employee.Type]();
}
static void Main(string[] args)
{
EmployeeManager me = new EmployeeManager { Name = "Me" };
Payments payments = new Payments();
Console.WriteLine(payments.Pay(me));
}










Sorry, But I Can’t get it. What is the advantage of using this pattern. I have to add another line of code in payment in payments class if I need to add a new EmployeeType such as supervisor. Is there any way to not change the Payment class if I need to add a new EmployeeType?
This patterns removes the project’s dependency on linear non-OOP methods like switch or if clauses. Of course this is only a short example and should not be applied as such to real projects, but adapted.
The advantage of having a dictionary over a switch statement is that you may have multiple sections in your code where you make the same check. Using a dictionary actually cleans up all of the sections and the only part changing is the dictionary it-self.
There are of course other methods you can implement if you want to keep the Payments class non-changeable, for this you can use a factory method, where your Payments class doesn’t change but it accesses child-methods to handle this calculation.
Or you can use State Model Design Pattern (https://dzone.com/articles/design-patterns-state)