Interface Segregation Principle Using C#

Introduction

 
In OOP (Object Oriented Programming) languages the solid principle plays a desired design role to make a class flexible and easy to understand. In that, we will see today the Interface segregation principle.
 

Why ISP?

 
When we design/develop a class, that class should not implement any such interfaces which are not required by the customer even if it is related to that class which we are designing or developing.
 
Let us see with an example, in which we'll sevelop a calculator for school, shops and for programmers.
 
When we say calculator many things will come into mind i.e. add, sub, div, multiplication, Trigonometry functions, Calculus, etc.
 
Below is the code which fulfills the requirement all 3 kinds of users mentioned above i.e. School, Shops and for Programmers
  1. using System;  
  2. using System.Linq;  
  3.   
  4. namespace Solid.Principle.ISP.Demo  
  5. {  
  6.     public class Calculator  
  7.     {  
  8.         /// <summary>  
  9.         /// This Method is for all kind of users  
  10.         /// </summary>  
  11.         /// <param name="nums"></param>  
  12.         /// <returns></returns>  
  13.         public int Add(params int[] nums)  
  14.         {  
  15.             return nums.Sum();  
  16.         }  
  17.   
  18.         /// <summary>  
  19.         /// This Method is for all kind of users  
  20.         /// </summary>  
  21.         /// <param name="a"></param>  
  22.         /// <param name="b"></param>  
  23.         /// <returns></returns>  
  24.         public int SubStract(int a, int b)  
  25.         {  
  26.             return a > b ? a - b : b - a;  
  27.         }  
  28.   
  29.         /// <summary>  
  30.         /// This Method is for all kind of users  
  31.         /// </summary>  
  32.         /// <param name="nums"></param>  
  33.         /// <returns></returns>  
  34.         public int Multplicaton(params int[] nums)  
  35.         {  
  36.             int result = 0;  
  37.             nums.ToList().ForEach(a => result = result * a);  
  38.             return result;  
  39.         }  
  40.   
  41.         /// <summary>  
  42.         /// This Method is for all kind of users  
  43.         /// </summary>  
  44.         /// <param name="a"></param>  
  45.         /// <param name="b"></param>  
  46.         /// <returns></returns>  
  47.         public int Division(int a, int b)  
  48.         {  
  49.             return a > b ? a/b : b/a;  
  50.         }  
  51.   
  52.         /// <summary>  
  53.         /// This Method is for School students  
  54.         /// </summary>  
  55.         /// <param name="x"></param>  
  56.         /// <returns></returns>  
  57.         public double SinOf(double x)  
  58.         {  
  59.             return Math.Sin(x);  
  60.         }  
  61.   
  62.         /// <summary>  
  63.         /// This Method is for School students  
  64.         /// </summary>  
  65.         /// <param name="x"></param>  
  66.         /// <returns></returns>  
  67.         public double CosOf(double x)  
  68.         {  
  69.             return Math.Cos(x);  
  70.         }  
  71.   
  72.         /// <summary>  
  73.         /// This Method is for School students  
  74.         /// </summary>  
  75.         /// <param name="x"></param>  
  76.         /// <returns></returns>  
  77.         public double TanOf(double x)  
  78.         {  
  79.             return Math.Tan(x);  
  80.         }  
  81.   
  82.         /// <summary>  
  83.         /// This method is for Programmer  
  84.         /// </summary>  
  85.         /// <param name="input"></param>  
  86.         /// <returns></returns>  
  87.         public string ConvertHexToBinary(string input)  
  88.         {  
  89.             return $"Add logic to Convert to Binary for hex input : {input}";  
  90.         }  
  91.   
  92.         /// <summary>  
  93.         ///  /// <summary>  
  94.         /// This method is for Programmer  
  95.         /// </summary>  
  96.         /// <param name="input"></param>  
  97.         /// <returns></returns>  
  98.         /// </summary>  
  99.         /// <param name="input"></param>  
  100.         /// <returns></returns>  
  101.         public string ConvertBinaryToHex(string input)  
  102.         {  
  103.             return $"Add logic to Convert to hex for Binary input : {input}";  
  104.         }  
  105.     }  
  106. }   
But if we observe the above code we can understand that we are giving some extra features which users may not be interested in (as the user won’t use it). For example, a shop holder needs only common functions like add, subtract, multiply, divide. this user doesn’t need Trigonometry functions and HexToBinary and Vice versa functions.
 
And school students need Common functions + Trigonometry functions + may need or may not need HexToBinary and Vice versa function.
 
But as we designed and developed class including all together we don’t have the option for segregation here. We need to deliver all features to end-user.
 
At this stage we ISP will play a key role. We can split the Calculator class into the below interface (Contracts).
  1. namespace Solid.Principle.ISP.Demo.Contract  
  2. {  
  3.     /// <summary>  
  4.     /// This Interface is for all kind of users  
  5.     /// </summary>  
  6.     public interface ICommonCalci  
  7.     {  
  8.         int Add(params int[] nums);  
  9.         int SubStract(int a, int b);  
  10.         int Multplicaton(params int[] nums);  
  11.         int Division(int a, int b);  
  12.     }  
  13. }  
  1. namespace Solid.Principle.ISP.Demo.Contract  
  2. {  
  3.     /// <summary>  
  4.     /// This Interface is for School/College students  
  5.     /// </summary>  
  6.     public interface ITrigonometryCalci  
  7.     {  
  8.         double SinOf(double x);  
  9.         double CosOf(double x);  
  10.         double TanOf(double x);  
  11.     }  
  12. }   
  1. namespace Solid.Principle.ISP.Demo.Contract  
  2. {  
  3.     /// <summary>  
  4.     /// This Interface is for Programmer  
  5.     /// </summary>  
  6.     public interface IProgrammerCalci  
  7.     {  
  8.         string ConvertHexToBinary(string input);  
  9.         string ConvertBinaryToHex(string input);  
  10.     }  
  11. }  
And below is the newly designed calculator class by inheriting all 3 interfaces. Based on user needs we can deliver the particular interface(s) to the user. 
  1. using Solid.Principle.ISP.Demo.Contract;  
  2. using System;  
  3. using System.Linq;  
  4.   
  5. namespace Solid.Principle.ISP.Demo  
  6. {  
  7.     public class Calculator : ICommonCalci, ITrigonometryCalci, IProgrammerCalci  
  8.     {  
  9.         /// <summary>  
  10.         /// This Method is for all kind of users  
  11.         /// </summary>  
  12.         /// <param name="nums"></param>  
  13.         /// <returns></returns>  
  14.         public int Add(params int[] nums)  
  15.         {  
  16.             return nums.Sum();  
  17.         }  
  18.   
  19.         /// <summary>  
  20.         /// This Method is for all kind of users  
  21.         /// </summary>  
  22.         /// <param name="a"></param>  
  23.         /// <param name="b"></param>  
  24.         /// <returns></returns>  
  25.         public int SubStract(int a, int b)  
  26.         {  
  27.             return a > b ? a - b : b - a;  
  28.         }  
  29.   
  30.         /// <summary>  
  31.         /// This Method is for all kind of users  
  32.         /// </summary>  
  33.         /// <param name="nums"></param>  
  34.         /// <returns></returns>  
  35.         public int Multplicaton(params int[] nums)  
  36.         {  
  37.             int result = 0;  
  38.             nums.ToList().ForEach(a => result = result * a);  
  39.             return result;  
  40.         }  
  41.   
  42.         /// <summary>  
  43.         /// This Method is for all kind of users  
  44.         /// </summary>  
  45.         /// <param name="a"></param>  
  46.         /// <param name="b"></param>  
  47.         /// <returns></returns>  
  48.         public int Division(int a, int b)  
  49.         {  
  50.             return a > b ? a/b : b/a;  
  51.         }  
  52.   
  53.         /// <summary>  
  54.         /// This Method is for School students  
  55.         /// </summary>  
  56.         /// <param name="x"></param>  
  57.         /// <returns></returns>  
  58.         public double SinOf(double x)  
  59.         {  
  60.             return Math.Sin(x);  
  61.         }  
  62.   
  63.         /// <summary>  
  64.         /// This Method is for School students  
  65.         /// </summary>  
  66.         /// <param name="x"></param>  
  67.         /// <returns></returns>  
  68.         public double CosOf(double x)  
  69.         {  
  70.             return Math.Cos(x);  
  71.         }  
  72.   
  73.         /// <summary>  
  74.         /// This Method is for School students  
  75.         /// </summary>  
  76.         /// <param name="x"></param>  
  77.         /// <returns></returns>  
  78.         public double TanOf(double x)  
  79.         {  
  80.             return Math.Tan(x);  
  81.         }  
  82.   
  83.         /// <summary>  
  84.         /// This method is for Programmer  
  85.         /// </summary>  
  86.         /// <param name="input"></param>  
  87.         /// <returns></returns>  
  88.         public string ConvertHexToBinary(string input)  
  89.         {  
  90.             return $"Add logic to Convert to Binary for hex input : {input}";  
  91.         }  
  92.   
  93.         /// <summary>  
  94.         ///  /// <summary>  
  95.         /// This method is for Programmer  
  96.         /// </summary>  
  97.         /// <param name="input"></param>  
  98.         /// <returns></returns>  
  99.         /// </summary>  
  100.         /// <param name="input"></param>  
  101.         /// <returns></returns>  
  102.         public string ConvertBinaryToHex(string input)  
  103.         {  
  104.             return $"Add logic to Convert to hex for Binary input : {input}";  
  105.         }  
  106.     }  
  107. }  
As per the above code, we can see that
  • For Shop holders we can provide an interface ICommonCalci
  • For Programmers we can provide ICommonCalci + IProgrammerCalci.
  • For Students we can provide ICommonCalci + ITrigonometryCalci + IProgrammerCalci (Based on Requirement)
This way we fulfilled all user requirements. And still this class is feasible to extend with new interfaces for new kinds of users and for new kinds of requirements.
 

Summary

 
In this article, we learned about the interface segregation principle. I attached the source code for this article. download and extend it for better understanding.