Switch Statement - A Code Smell

This article will explain the code issues, using the Switch.. case statement. In some cases, it is a type of code smell.

Introduction

Switch... Case statement is used for conditional operations. Sometimes, it is considered in the category of code smell. Switch case is not a bad syntax, but its usage in some cases categorizes it under code smell. It is considered a smell, if it is being used in OOPS. Thus, Switch case should be used very carefully.

Why is Switch... case considered as a code smell?

Switch...case is considered as a code smell due to the reasons given below.
  • Violation of Open and close principle
    Each time a developer wants to add a new type then he or she has to insert new switch.. case in each section. It promotes modification of an existing code.

  • Difficult to maintain
    Switch... case can grow on the basis of new requirements. Switch case is being kept in a single function, so function will increase and and maintenance will be hard.

  • Provides the chances of Redundant Code
    Switch... case provides the redundant code in some cases. The code given below is an example of containing lots of redundant codes.
  1. switch(input)  
  2. {  
  3.    case "a":  
  4.      CreateValue("Hello");  
  5.      myData+= "Hello";  
  6.   
  7.    case "b":  
  8.      CreateValue("Hi");  
  9.      myData+= "Hi";  
  10.   
  11.    case "C":  
  12.      CreateValue("Hey");  
  13.      myData+= "Hey";  
  14.   
  15.    default:  
  16.      myData = string.empty;  
  17. }  
Switching on type is a bad OOP style of programming, however switching on a value is fine.

How to Refactor the issue of code smell in Case...switch?

Switch... case can be refactored by using Polymorphism and strategy pattern with pattern searching. 
 
The code given below is an example of Switch...case statement.
  1. public List<string> GetSortedData(string searchType, List<string> data)  
  2.         {  
  3.             List<string> sortedData = null;  
  4.      
  5.             switch (searchType)  
  6.             {  
  7.                 case "BubbleSort":  
  8.                     //Peform Bubble sort and assign to data.  
  9.                     sortedData = data;  
  10.                     break;  
  11.   
  12.                 case "HeapSort":  
  13.                     //Peform Heap sort and assign to data.  
  14.                     sortedData = data;  
  15.                     break;  
  16.   
  17.                 case "MergeSort":  
  18.                     //Peform Merge sort and assign to data.  
  19.                     sortedData = data;  
  20.                     break;  
  21.   
  22.                 case "InsertionSort":  
  23.                     //Peform Insertion sort and assign to data.  
  24.                     sortedData = data;  
  25.                     break;  
  26.             }  
  27.   
  28.             return sortedData;  
  29.         }  
In the code example given above, if a new sort type case is needed then the existing method will be modified and code sortedData for the assignment of the sorted data is redundant.

Thus, the code given below is an example with Polymorphism, strategy pattern, and pattern search. 
  1. public interface ISortData  
  2. {  
  3.     List<string> GetSortedData(List<string> data);  
  4. }  
  5.   
  6. public class BubbleSortData : ISortData  
  7. {  
  8.     public List<string> GetSortedData(List<string> data)  
  9.     {  
  10.         //implement bubble sort and sort the data and return it.  
  11.         return data;  
  12.     }  
  13. }  
  14.   
  15. public class HeapSortData : ISortData  
  16. {  
  17.     public List<string> GetSortedData(List<string> data)  
  18.     {  
  19.         //implement Heap sort and sort the data and return it.  
  20.         return data;  
  21.     }  
  22. }  
  23.   
  24. public class MergeSortData : ISortData  
  25. {  
  26.     public List<string> GetSortedData(List<string> data)  
  27.     {  
  28.         //implement Merge sort and sort the data and return it.  
  29.         return data;  
  30.     }  
  31. }  
  32.   
  33. public class InsertionSortData : ISortData  
  34. {  
  35.     public List<string> GetSortedData(List<string> data)  
  36.     {  
  37.         //implement Insertion sort and sort the data and return it.  
  38.         return data;  
  39.     }  
  40. }  
  41.   
  42. public class SortingContext  
  43. {  
  44.      private Dictionary<string, ISortData> sortStrategy = new Dictionary<string, ISortData>();  
  45.   
  46.     public SortingContext()  
  47.     {  
  48.         sortStrategy.Add("BubbleSort"new BubbleSortData());  
  49.         sortStrategy.Add("HeapSort"new HeapSortData());  
  50.         sortStrategy.Add("MergeSort"new MergeSortData());  
  51.         sortStrategy.Add("InsertionSort"new InsertionSortData());  
  52.     }  
  53.   
  54.     public List<string> GetSortedData(string searchType, List<string> data)  
  55.     {  
  56.         return sortStrategy[searchType].GetSortedData(data);  
  57.     }  
  58. }  
  59.   
  60. public class SortingClient  
  61. {  
  62.     List<string> data = new List<string> { "Ball""Apple""Cat" };  
  63.     SortingContext sortingContext = new SortingContext();  
  64.     List<string> result = sortingContext.GetSortedData("BubbleSort", data);  
  65. }  

Conclusion

Switch... case is normally a very good conditional statement but in some cases, especially with OOPS, it gives birth to the code smell issue. This issue breaks some laws of the code design. Thus, it can be refactored by using polymorphism, strategy pattern, pattern searching etc.