Exploring SOLID Principles in .NET Core Applications — part 4

Abiodun Maborukoje
3 min readSep 24, 2023

--

New to .NET Core development? Let’s delve into SOLID principles to enhance your coding skills. This is part three of a series of five see the previous part here

Interface Segregation Principle (ISP)

The Interface Segregation Principle (ISP) is one of the SOLID principles, and it emphasizes that clients should not be forced to depend on interfaces they don’t use. In other words, you should create small and focused interfaces tailored to the specific needs of the clients that use them. This ensures that classes only implement the methods that are relevant to their behaviour. Here’s an explanation and code samples that first violate ISP and then adhere to it.

Explanation:

Violating ISP often leads to large, monolithic interfaces that force clients to implement methods they don’t need, resulting in unnecessary coupling and complexity.

Adhering to ISP means designing interfaces that are specific to the needs of the clients that use them, promoting loose coupling and better maintainability.

Let’s start with a code sample that violates ISP:

// Violating ISP: A single interface with methods that are not relevant to all clients.

public interface INotificationService
{
void SendEmailNotification(User user, string message);
void SendSmsNotification(User user, string message);
void SendPushNotification(User user, string message);
}

public class EmailNotificationService : INotificationService
{
public void SendEmailNotification(User user, string message)
{
// Logic to send an email notification
Console.WriteLine($"Email sent to {user.Email}: {message}");
}

// Violation: Implementing an unnecessary method
public void SendSmsNotification(User user, string message)
{
// This method should not be here
Console.WriteLine($"SMS sent to {user.PhoneNumber}: {message}");
}

public void SendPushNotification(User user, string message)
{
// This method should not be here
Console.WriteLine($"Push notification sent to {user.DeviceId}: {message}");
}
}

In this code, we have a single INotificationService interface with methods for sending email, SMS, and push notifications. However, not all implementations of this interface need all three methods. The EmailNotificationService class violates ISP by implementing an unnecessary method for sending push notifications, even though it doesn't need it.

Now, let’s refactor the code to adhere to ISP by creating smaller, focused interfaces:

// Adhering to ISP: Smaller, focused interfaces for specific use cases.

public interface IEmailNotification
{
void SendEmailNotification(User user, string message);
}

public interface ISmsNotification
{
void SendSmsNotification(User user, string message);
}

public class EmailNotificationService : IEmailNotification
{
public void SendEmailNotification(User user, string message)
{
// Logic to send an email notification
Console.WriteLine($"Email sent to {user.Email}: {message}");
}
}

public class SmsNotificationService : ISmsNotification
{
public void SendSmsNotification(User user, string message)
{
// Logic to send an SMS notification
Console.WriteLine($"SMS sent to {user.PhoneNumber}: {message}");
}
}

In this refactored code:

  • We’ve created separate interfaces IEmailNotification and ISmsNotification, each focused on a specific use case.
  • The EmailNotificationService and SmsNotificationService classes implement the respective interfaces and provide the necessary methods.

This adheres to the Interface Segregation Principle because each interface is tailored to a specific use case, and clients (e.g., classes that use these interfaces) are not forced to implement methods they don’t need. It promotes a cleaner and more maintainable design.

Click here for Part — 5

--

--

Abiodun Maborukoje

A seasoned Software Engineer with years of experience specializing in crafting advanced software solutions.