Introduction
This article explains the Strategy Design Pattern that is a very simple design pattern. This design pattern simplifies the code and also makes the code maintainable. This design pattern is also intended to remove the logic that we write in if else statements in our code and makes the code maintainable and cleaner. This design pattern does not indicate any new functionality. it is just the basic functionality of interfaces. I wanted to write this article because after implementing this functionality I have seen better code metric results in my projects.
I will explain this with an example. Suppose we have a class Employee that has one method CalculatePay that calculates the pay of an employee based upon employee type, in other words Regular Employee or PartTime Employee. Calculations are done in the if else part of the statements.
The following is a sample class for that:
- class Employee
- {
- public decimal CalculatePay(string employeeType)
- {
- if (employeeType == "RegularEmployee")
- {
-
- }
- else
- {
-
- }
- return 0;
- }
- }
The code for calling the preceding method is:
- string employeeType = string.Empty;
- Employee emp = new Employee();
- if (employeeType == "RegularEmployee")
- {
- emp.CalculatePay("RegularEmployee");
- }
- else
- {
- emp.CalculatePay("PartTimeEmployee");
- }
The preceding class is a dummy class and it simply represents the way we will do that.
This code will run fine but it is not maintainable because if we need to add another condition, in other words if a new type of employee is to be added then we must make changes in the code and that is not a good approach. Moreover if we run the code metrics for this code (that can be found under the Analyze option of the toolbar in Visual Studio) then we will get the following results:
The maintainability index indicates how maintainable our code is and the Cyclomatic complexity indicates the complexity level of our code. I will explain all these metrics in detail in my next article.
The preceding score is a very good score and it should be because we have not written the actual code. Now to improve it further I will provide you an overview of the Strategy Design Pattern. According to this design pattern we should create multiple implementations of the same process and put that under a wrapper so that we can call the specific implementation at run time. For doing that we will find the common functionality in our code and create an interface for that. Then we will create separate classes that will implement our interface and contain different implementations of the same method. In this case we will create an IEmployee interface and put one method CalculatePay in that.
- interface IEmployee
- {
- decimal CalculatePay();
- }
Now we will create two separate classes that will implement our interface. These classes will contain the different code for the same task.
- class RegularEmployee : IEmployee
- {
- public decimal CalculatePay()
- {
- return 0;
- }
- }
- class PartTimeEmployee : IEmployee
- {
- public decimal CalculatePay()
- {
- return 0;
- }
- }
Now we will create an object of type IEmployee and instantiate that depending on the type of employee at run time.
- string employeeType = string.Empty;
- IEmployee emp;
- if (employeeType == "RegularEmployee")
- {
- emp = new RegularEmployee();
- }
- else
- {
- emp = new PartTimeEmployee();
- }
- emp.CalculatePay();
This code is maintainable since we don't need to make changes in the if else part, if the implementation of our code changes and if in the future we have more classes to implement then we will create a new class and implement the same interface with the desired code. Moreover if we run the code metrics for this code we will get the different results.
As you can see that this code's maintainability index has been raised to 92 after implementing the code with interfaces that clearly indicate that the code becomes maintainable after implementing the Strategy Design Pattern.