I will show you how we can refactor an if else-if or switch case statement code block in more batter way.
Though I'm using C# language here but you can use this approach in other programming languages too.
Before Refactoring
Let's we have a switch statement code block in our application which returns the Excel file name depending on ExportType
enum.
public string GetReportFileName(ExportType exportType) { string fileName; switch (exportType) { case ExportType.MemberDataVersioning: fileName = "MemberList.xls"; break; case ExportType.MemberProfileInformation: fileName = "MemberProfile.xls"; break; case ExportType.MemberOtherDataVersioningDetails: fileName = "MemberRecords.xls"; break; case ExportType.ProviderDataVersioning: fileName = "ProviderList.xls"; break; case ExportType.ProviderProfileInformation: fileName = "ProviderProfile.xls"; break; case ExportType.ProviderOtherDataVersioningDetails: fileName = "ProviderRecords.xls"; break; case ExportType.ClaimsDataVersioning: fileName = "ClaimList.xls"; break; case ExportType.ClaimsDataChangeLog: fileName = "ClaimDataChangeLog.xls"; break; case ExportType.ElementWiseValidationReport: fileName = "ElementDetails.xls"; break; case ExportType.ReconciliationReport: fileName = "RecociliationReport.xls"; break; default: fileName = exportType.ToString() + ".xls"; break; } return fileName; }When a new export type will come then we have to add another switch case statement and will continue this process for every new export type.
After Refactoring
There is nice refactoring way which we can apply to improve the code quality and simplicity.
We can use a dictionary instead of the switch statement. Let's we declare a dictionary of report file types in constructor:
We can use a dictionary instead of the switch statement. Let's we declare a dictionary of report file types in constructor:
private readonly Dictionary<ExportType, string> reportFileNames; public ReportFileHelper() { this.reportFileNames = new Dictionary<ExportType, string> { { ExportType.MemberDataVersioning, "MemberList.xls" }, { ExportType.MemberProfileInformation, "MemberProfile.xls" }, { ExportType.MemberOtherDataVersioningDetails, "MemberRecords.xls" }, { ExportType.ProviderDataVersioning, "ProviderList.xls" }, { ExportType.ProviderProfileInformation, "ProviderProfile.xls" }, { ExportType.ProviderOtherDataVersioningDetails, "ProviderRecords.xls" }, { ExportType.ClaimsDataVersioning, "ClaimList.xls" }, { ExportType.ClaimsDataChangeLog, "ClaimChangeLog.xls" }, { ExportType.ElementWiseValidationReport, "ElementDetails.xls" }, { ExportType.ReconciliationReport, "RecociliationReport.xls" } }; }Now we can easily refactore the GetReportFileName method with this simple lines of code:
public string GetReportFileName(ExportType exportType) { string fileName; return reportFileNames.TryGetValue(exportType, out fileName) ? fileName : (exportType.ToString() + ".xls"); }
When a new report type comes, we will just add an item in reportFileNames dictionary.
Similarly, we can also use this refactoring approach in the if else-if statement.
Before Refactoring
Let's we have a function which return a customer object based on customer type.
Here is the code block:
public ICustomer GetCustomer(CustomerType customerType) { ICustomer customer = null; if (customerType == CustomerType.Gold) { customer = new GoldCustomer(); } else if (customerType == CustomerType.Platinum) { customer = new PlatinumCustomer(); } else if (customerType == CustomerType.Silver) { customer = new SilverCustomer(); } else if (customerType == CustomerType.Normal) { customer = new NormalCustomer(); } return customer; }
After Refactoring
We will declare a dictionary in the constructor. Here I have used Func of the customer.
Func is a very nice feature in c#. you can get details from here.
private readonly Dictionary<CustomerType, Func<ICustomer>> customerTypes; public CustomerFactory() { this.customerTypes = new Dictionary<CustomerType, Func<ICustomer>> { { CustomerType.Gold, () => new GoldCustomer() }, { CustomerType.Platinum, () => new PlatinumCustomer() }, { CustomerType.Silver, () => new SilverCustomer() }, { CustomerType.Normal, () => new NormalCustomer() }, }; }
Now we can replace the GetCustomer method in this way.
public ICustomer GetCustomer(CustomerType customerType) { Func<ICustomer> customer; return this.customerTypes.TryGetValue(customerType, out customer) ? customer() : null; }
But what about performance? Do you check bench mark?
ReplyDelete