DEV Community

Cover image for SOLID: The Interface Segregation Principle(ISP) in C#
Aditya Sharma
Aditya Sharma

Posted on

SOLID: The Interface Segregation Principle(ISP) in C#

Introduction

The SOLID principles are essential guidelines for building robust, maintainable, and scalable software. Among these, the Interface Segregation Principle (ISP) ensures that no client is forced to depend on methods it does not use.

Seperation

Let's delve into the "I" of SOLID with examples in C#.

What is the Interface Segregation Principle?

The Interface Segregation Principle states:

“A client should not be forced to implement an interface it does not use."

In simpler terms, large, unwieldy interfaces should be broken down into smaller, more specific interfaces. This helps to prevent "fat interfaces," where a class is burdened with irrelevant functionality.

Interface segregation

Let’s explore this concept with simple examples in C#.

Problem: A Large Interface ❌

Imagine you’re designing a system for animals in a zoo. You create an interface IAnimal that defines common actions:

public interface IAnimal
{
    void Eat();
    void Fly();
    void Swim();
}
Enter fullscreen mode Exit fullscreen mode

At first glance, this seems fine. But what if you have a dog that can eat and swim but cannot fly? It would still need to implement the Fly method, even though it doesn’t make sense for it.

Here’s what the implementation might look like:

public class Dog : IAnimal
{
    public void Eat()
    {
        Console.WriteLine("The dog is eating.");
    }

    public void Fly()
    {
        throw new NotImplementedException("Dogs cannot fly.");
    }

    public void Swim()
    {
        Console.WriteLine("The dog is swimming.");
    }
}
Enter fullscreen mode Exit fullscreen mode

This design forces the Dog class to implement unnecessary methods, violating ISP.

Solution: Smaller Interfaces ✔

split-up

To fix this, we can split IAnimal into smaller interfaces based on specific abilities:

public interface IEater
{
    void Eat();
}

public interface IFlyer
{
    void Fly();
}

public interface ISwimmer
{
    void Swim();
}
Enter fullscreen mode Exit fullscreen mode

Now, each class can implement only the interfaces it needs:

public class Dog : IEater, ISwimmer
{
    public void Eat()
    {
        Console.WriteLine("The dog is eating.");
    }

    public void Swim()
    {
        Console.WriteLine("The dog is swimming.");
    }
}

public class Bird : IEater, IFlyer
{
    public void Eat()
    {
        Console.WriteLine("The bird is eating.");
    }

    public void Fly()
    {
        Console.WriteLine("The bird is flying.");
    }
}

public class Fish : IEater, ISwimmer
{
    public void Eat()
    {
        Console.WriteLine("The fish is eating.");
    }

    public void Swim()
    {
        Console.WriteLine("The fish is swimming.");
    }
}
Enter fullscreen mode Exit fullscreen mode

By splitting the interfaces, each class only implements what it needs, making the code cleaner and easier to maintain.

Benefits of Following ISP

  1. No Unnecessary Methods: Classes don’t need to implement methods they don’t use.
  2. Improved Maintainability: Small interfaces are easier to understand and modify.
  3. Better Flexibility: Changes in one interface don’t affect unrelated classes.

To-do:

  1. Create focused interfaces: Break down large interfaces into smaller, more specific ones.
  2. Reduce unused methods: Ensure that classes don’t have to implement irrelevant methods.
  3. Simplify testing and maintenance: Smaller interfaces mean simpler, cleaner code.

Let connect on LinkedIn and checkout my GitHub repos:

Thank-you

What do you think about ISP? Share your thoughts in the comments below!

Top comments (0)