Interface Segregation Principle (ISP) in .NET 6 Core

As we navigate the SOLID principles in the realm of .NET 6 Core, the Interface Segregation Principle (ISP) takes center stage. This principle emphasizes creating specialized interfaces for clients rather than imposing broad, one-size-fits-all contracts.

What is the Interface Segregation Principle (ISP)?

The Interface Segregation Principle, represented by the "I" in SOLID, advocates for the creation of specific interfaces tailored to the needs of clients. In essence, a class should not be forced to implement interfaces it does not use. Think of it as providing specialized tools to different workers rather than a single tool with features they don't need.

Why is ISP Important?

  1. Modularity: Specialized interfaces promote modularity by allowing clients to implement only what they need.
  2. Readability: Code becomes more readable as interfaces are focused on specific functionalities.
  3. Adaptability: Clients can adapt to changes without being burdened by unnecessary methods.

A .NET 6 Core Example Using Specialized Interfaces

Let's expand our example by introducing interfaces specific to different aspects of our library system. We'll create IBookInfo for retrieving book information and ILateFeeCalculator for calculating late fees.

Reservation classes were used in our previous article on the Single Responsibility Principle (SRP), Open-Closed Principle (OCP), and Liskov Substitution Principle (LSP).

 If you haven't read it yet, you can check it out.

IBookInfo Interface

public interface IBookInfo
{
    string GetTitle();
    string GetAuthor();
    string GetISBN();
}

ILateFeeCalculator Interface

public interface ILateFeeCalculator
{
    decimal CalculateLateFee(DateTime dueDate);
}

Modified Book and EBook Classes

public class Book : IBookInfo
{
    // ... existing properties and methods

    public string GetTitle() => Title;
    public string GetAuthor() => Author;
    public string GetISBN() => ISBN;
}

public class EBook : Book, IBookInfo, ILateFeeCalculator
{
    // ... existing properties and methods

    public decimal CalculateLateFee(DateTime dueDate)
    {
        // Calculate late fee for EBooks
        // For example, $1 per day late fee
        TimeSpan overdue = DateTime.Now - dueDate;
        return overdue.TotalDays * 1.0M;
    }
}

Applying ISP in our Library System

Now, let's ensure that our classes seamlessly implement the specialized interfaces they need, adhering to the Interface Segregation Principle.

public class Reservation
{
    private readonly IBookInfo _bookInfo;
    private readonly ILateFeeCalculator _lateFeeCalculator;

    public Reservation(IBookInfo bookInfo, ILateFeeCalculator lateFeeCalculator)
    {
        _bookInfo = bookInfo;
        _lateFeeCalculator = lateFeeCalculator;
    }

    public void DisplayBookDetails()
    {
        Console.WriteLine($"Title: {_bookInfo.GetTitle()}, Author: {_bookInfo.GetAuthor()}, ISBN: {_bookInfo.GetISBN()}");
    }

    public decimal CalculateLateFee(DateTime dueDate)
    {
        return _lateFeeCalculator.CalculateLateFee(dueDate);
    }
}

In this example, we've tailored interfaces to specific functionalities, ensuring that classes only implement what they need. Our Reservation class now relies on specialized interfaces, following the Interface Segregation Principle.

Conclusion

Understanding the Interface Segregation Principle is key to crafting interfaces that cater to the needs of clients without imposing unnecessary methods. In our .NET 6 Core example, we've embraced ISP by creating specialized interfaces for book information and late fee calculation. As you continue honing your software design skills, remember that creating modular and adaptable interfaces contributes to building scalable and maintainable systems.

😊Please consider liking and following me for more articles and if you find this content helpful.👍


Citiustech Healthcare Technology Pvt Ltd
CitiusTech plays a deep and meaningful role in powering the future of healthcare.