Skip to main content

SOLID Principles - Interface Segregation Principle (ISP) Real-Time Example in C#

The SOLID Principles are the design principles that enable us to manage several software design problems. These principles provide us with ways to move from tightly coupled code to loosely coupled and encapsulated real business needs properly. Also readable, adaptable, and scalable code.

The SOLID Principles guide developers as they write readable, adaptable, and scalable code or design an application.

The SOLID Principles can be applied to any OOP program.

The SOLID Principles were developed by computer science instructor and author Robert C. Martin. Now, SOLID principles have also been adopted in both agile development and adaptive software development.

The 5 principles of SOLID are:

1.      Single Responsibility Principle (SRP)

2.      Open Closed Principle (OCP)

3.      Liskov Substitution Principle (LSP)

4.      Interface Segregation Principle (ISP)

5.      Dependency Inversion Principle (DIP)

 

SOLID Principle: (4) Interface Segregation Principle (ISP)

The Interface Segregation Principle (ISP) is one of the SOLID principles of object-oriented design.

By Robert C. Martin -

Interface Segregation Principle (ISP) states that clients should not be forced to implement interfaces they do not use.

Interface Segregation Principle (ISP) splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods they actually need.

 

Implementation:  Interface Segregation Principle (ISP) C# Live Example:

Let us consider an example to Explain the Interface Segregation Principle (ISP) in C#, suppose we have an IWorker interface that defines methods for various types of work, such as Work, Eat, and Sleep.

 

First, define an interface IWorker interface that has three methods Work (), Eat (), and Sleep ():

//IWorker interface

public interface IWorker

{

    void Work();

    void Eat();

    void Sleep();

}

Now, imagine we have two classes, HumanWorker and RobotWorker, that implement to IWorker interface.


Second, define a HumanWorker class that implements the IWorker interface:

//HumanWorker class that implements to IWorker interface

public class HumanWorker: IWorker

{

    public void Work() { /*...*/ }

    public void Eat() { /*...*/ }

    public void Sleep() { /*...*/ }

}


Third, define a RobotWorker class that also implements the IWorker interface. The Robot cannot Eat and Sleep but is forced to Eat () and Sleep () methods (violates the ISP):

//RobotWorker class that implements to IWorker interface

public class RobotWorker : IWorker

{

    public void Work() { /*...*/ }

 

    /* Not needed for robots worker because they not eat food. */

    public void Eat() { /*...*/ }

 

    /* Not needed for robots worker because they not eat sleep. */

    public void Sleep() { /*...*/ }

}

Here IWorker interface violates the Interface Segregation Principle (ISP) and it's forcing the RobotWorker class to implement the Eat () and Sleep () methods that are irrelevant to the robot’s class.

To fix the issue of violating the Interface Segregation Principle (ISP), we need to break down the large interface into smaller ones.

Let's break down the IWorker interface into smaller, See the C# code,

//IWorkable interface

public interface IWorkable

{

    void Work();

}

 

//IEatable interface

public interface IEatable

{

    void Eat();

}

 

//ISleepable interface

public interface ISleepable

{

    void Sleep();

}

 

Now, the HumanWorker class will implement all three interfaces (IWorkable, IEatable, ISleepable), while the RobotWorker class only needs to implement the (IWorkable) interface. See the C# code,

//HumanWorker class and inherited to IWorkable, IEatable, ISleepable interfaces

public class HumanWorker: IWorkable, IEatable, ISleepable

{

    public void Work() { /*...*/ }

    public void Eat() { /*...*/ }

    public void Sleep() { /*...*/ }

}

 

//RobotWorker class and inherited only IWorkable interface

public class RobotWorker: IWorkable

{

    public void Work() { /*...*/ }

}

 

Now we have ensured that clients only implement the methods they actually need.


Put it all together to follow the Interface Segregation Principle (ISP) in C#,

 

namespace ISP;

 

public interface IWorkable

{

    void Work();

}

public interface IEatable

{

    void Eat();

}

public interface ISleepable

{

    void Sleep();

}

public class HumanWorker: IWorkable, IEatable, ISleepable

{

    public void Work () {/*...*/}

    public void Eat () {/*...*/}

    public void Sleep () {/*...*/}

}

 

public class RobotWorker: IWorkable

{

    public void Work () {/*...*/}

}

public class Program

{

    public static void Main(string[] args)

    {

        // HumanWorker

        var homenWorker = new HumanWorker();

        homenWorker.Work();

        homenWorker.Eat();

        homenWorker.Sleep();

 

        // RobotWorker

        var robotWorker = new RobotWorker();

        robotWorker.Work();

    }

}


What Are the Advantages of Interface Segregation Principle (ISP) in C#?

1.     Reduced Dependencies: Breaking interfaces into smaller, more specific ones reduces the number of methods each class is required to implement.

2.     Improved Code Maintainability: With smaller, more focused interfaces, it becomes easier to understand and maintain the code.

3.     Flexibility and Extensibility: Classes developed by the ISP are more flexible and extensible.

4.     Easier Testing: Smaller interfaces make it easier to create and perform unit tests.

5.     Avoiding Fat Interfaces: ISP prevents the creation of "fat interfaces". Fat interfaces violate the single responsibility principle. Breaking down interfaces helps avoid this issue.

6.     Clearer Intent: Specific interfaces convey the intent and responsibilities of implementing classes more clearly. This makes the codebase more self-documenting and easier to understand.

 What Are the Disadvantages of Interface Segregation Principle (ISP) in C#?

1.     Increased Number of Interfaces: More interfaces will create the challenge to manage and understand the relationships between various interfaces.

2.     Increased Development Time: Creating and managing a large number of small interfaces might increase the time and effort required during the development phase.

How to use the Interface Segregation Principle effectively in C#?

1.     Identify Client Needs: To identify the client needs and split fat interfaces into smaller ones.

2.     Refactor Existing Interfaces

3.     Avoid Fat Interfaces

4.     Apply Dependency Injection

 

By Anil Singh | Rating of this article (*****)

Popular posts from this blog

nullinjectorerror no provider for httpclient angular 17

In Angular 17 where the standalone true option is set by default, the app.config.ts file is generated in src/app/ and provideHttpClient(). We can be added to the list of providers in app.config.ts Step 1:   To provide HttpClient in a standalone app we could do this in the app.config.ts file, app.config.ts: import { ApplicationConfig } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; //This (provideHttpClient) will help us to resolve the issue  import {provideHttpClient} from '@angular/common/http'; export const appConfig: ApplicationConfig = {   providers: [ provideRouter(routes),  provideClientHydration(), provideHttpClient ()      ] }; The appConfig const is used in the main.ts file, see the code, main.ts : import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from ...

List of Countries, Nationalities and their Code In Excel File

Download JSON file for this List - Click on JSON file    Countries List, Nationalities and Code Excel ID Country Country Code Nationality Person 1 UNITED KINGDOM GB British a Briton 2 ARGENTINA AR Argentinian an Argentinian 3 AUSTRALIA AU Australian an Australian 4 BAHAMAS BS Bahamian a Bahamian 5 BELGIUM BE Belgian a Belgian 6 BRAZIL BR Brazilian a Brazilian 7 CANADA CA Canadian a Canadian 8 CHINA CN Chinese a Chinese 9 COLOMBIA CO Colombian a Colombian 10 CUBA CU Cuban a Cuban 11 DOMINICAN REPUBLIC DO Dominican a Dominican 12 ECUADOR EC Ecuadorean an Ecuadorean 13 EL SALVA...

39 Best Object Oriented JavaScript Interview Questions and Answers

Most Popular 37 Key Questions for JavaScript Interviews. What is Object in JavaScript? What is the Prototype object in JavaScript and how it is used? What is "this"? What is its value? Explain why "self" is needed instead of "this". What is a Closure and why are they so useful to us? Explain how to write class methods vs. instance methods. Can you explain the difference between == and ===? Can you explain the difference between call and apply? Explain why Asynchronous code is important in JavaScript? Can you please tell me a story about JavaScript performance problems? Tell me your JavaScript Naming Convention? How do you define a class and its constructor? What is Hoisted in JavaScript? What is function overloadin...

25 Best Vue.js 2 Interview Questions and Answers

What Is Vue.js? The Vue.js is a progressive JavaScript framework and used to building the interactive user interfaces and also it’s focused on the view layer only (front end). The Vue.js is easy to integrate with other libraries and others existing projects. Vue.js is very popular for Single Page Applications developments. The Vue.js is lighter, smaller in size and so faster. It also supports the MVVM ( Model-View-ViewModel ) pattern. The Vue.js is supporting to multiple Components and libraries like - ü   Tables and data grids ü   Notifications ü   Loader ü   Calendar ü   Display time, date and age ü   Progress Bar ü   Tooltip ü   Overlay ü   Icons ü   Menu ü   Charts ü   Map ü   Pdf viewer ü   And so on The Vue.js was developed by “ Evan You ”, an Ex Google software engineer. The latest version is Vue.js 2. The Vue.js 2 is very similar to Angular because Evan ...

React | Encryption and Decryption Data/Text using CryptoJs

To encrypt and decrypt data, simply use encrypt () and decrypt () function from an instance of crypto-js. Node.js (Install) Requirements: 1.       Node.js 2.       npm (Node.js package manager) 3.       npm install crypto-js npm   install   crypto - js Usage - Step 1 - Import var   CryptoJS  =  require ( "crypto-js" ); Step 2 - Encrypt    // Encrypt    var   ciphertext  =  CryptoJS . AES . encrypt ( JSON . stringify ( data ),  'my-secret-key@123' ). toString (); Step 3 -Decrypt    // Decrypt    var   bytes  =  CryptoJS . AES . decrypt ( ciphertext ,  'my-secret-key@123' );    var   decryptedData  =  JSON . parse ( bytes . toString ( CryptoJS . enc . Utf8 )); As an Example,   import   React   from ...