Summary
Principle Name | Interface Segregation Principle |
Acronym | ISP |
Principle Type | SOLID |
Tagline | Create fine-grained interfaces, instead of big fat interfaces. |
Implementing Design Patterns | Adapter Pattern Decorator Pattern Facade Pattern Observer Pattern Proxy Pattern |
Related Principles | Single Responsibility Principle(SRP) Open/Closed Principle(OCP) Liskov Substitution Principle(LSP) Dependency Inversion Principle(DIP) |
Definition
Interface Segregation Principle(ISP) is the fourth principle of the SOLID Principles.
While coding over time we might create big bloating interfaces, with many methods. Then when a class tries to implement those interfaces, it has to deal with a lot of those unnecessary methods, which we do not need for the class.
These fat interfaces include unnecessary methods, which are not required for most of the classes. This ISP gives us guidelines deal with these fat interfaces.
The Interface Segregation Principle says-
We should create smaller and more specific interfaces, instead of having large monolithic interface with many methods.
Each interface should only contain methods that are relevant to the purpose of the interface. Then classes can implement one or more of those interfaces are required. Also, a class should only implement the interface(s) which are required.
The purpose of this principle is that- the client should not be forced to depend on methods, it does not use. Also, a client should not be forced to implement/depend on interfaces, that it does not use.
By avoiding those big fat interfaces, and instead creating multiple smaller interfaces, we ensure flexibility and frictionless changes in the future.
Implementation
Let’s first see what a fat interface looks like. Check the interface below where we are managing operations by user.
But it includes all types of operations for the user, like sending notifications, and reports.
If some class just needs to implement the CRUD operations for a user, and it implements the interface, then it has to also implement(probably leave blank) those notification and report-related methods.
// UserManager.java
public interface UserManager {
void createUser(String username, String password);
void deleteUser(int userId);
void updateUser(int userId, String username, String password);
void sendEmailNotification(int userId, String subject, String body);
void sendSmsNotification(int userId, String message);
void generateUserReport(int userId);
}
Javafrom abc import ABC, abstractmethod
class UserManager(ABC):
@abstractmethod
def create_user(self, username: str, password: str):
pass
@abstractmethod
def delete_user(self, user_id: int):
pass
@abstractmethod
def update_user(self, user_id: int, username: str, password: str):
pass
@abstractmethod
def send_email_notification(self, user_id: int, subject: str, body: str):
pass
@abstractmethod
def send_sms_notification(self, user_id: int, message: str):
pass
@abstractmethod
def generate_user_report(self, user_id: int):
pass
Pythonpackage main
// UserManager interface
type UserManager interface {
CreateUser(username string, password string)
DeleteUser(userId int)
UpdateUser(userId int, username string, password string)
SendEmailNotification(userId int, subject string, body string)
SendSmsNotification(userId int, message string)
GenerateUserReport(userId int)
}
Go<?php
// UserManager.php
interface UserManager {
public function createUser(string $username, string $password);
public function deleteUser(int $userId);
public function updateUser(int $userId, string $username, string $password);
public function sendEmailNotification(int $userId, string $subject, string $body);
public function sendSmsNotification(int $userId, string $message);
public function generateUserReport(int $userId);
}
PHP// UserManager.ts
interface UserManager {
createUser(username: string, password: string): void;
deleteUser(userId: number): void;
updateUser(userId: number, username: string, password: string): void;
sendEmailNotification(userId: number, subject: string, body: string): void;
sendSmsNotification(userId: number, message: string): void;
generateUserReport(userId: number): void;
}
TypeScriptWe should break down the interface into multiple fine-grained, smaller interfaces. Here we have broken this fat into 3 small interfaces.
Check the code below-
// User.java
public interface User {
void createUser(String username, String password);
void deleteUser(int userId);
void updateUser(int userId, String username, String password);
}
// UserNotification.java
public interface UserNotification {
void sendEmailNotification(int userId, String subject, String body);
void sendSmsNotification(int userId, String message);
}
// UserReporting.java
public interface UserReporting {
void generateUserReport(int userId);
}
Javafrom abc import ABC, abstractmethod
class User(ABC):
@abstractmethod
def create_user(self, username: str, password: str):
pass
@abstractmethod
def delete_user(self, user_id: int):
pass
@abstractmethod
def update_user(self, user_id: int, username: str, password: str):
pass
class UserNotification(ABC):
@abstractmethod
def send_email_notification(self, user_id: int, subject: str, body: str):
pass
@abstractmethod
def send_sms_notification(self, user_id: int, message: str):
pass
class UserReporting(ABC):
@abstractmethod
def generate_user_report(self, user_id: int):
pass
Pythonpackage main
// User interface
type User interface {
CreateUser(username string, password string)
DeleteUser(userId int)
UpdateUser(userId int, username string, password string)
}
// UserNotification interface
type UserNotification interface {
SendEmailNotification(userId int, subject string, body string)
SendSmsNotification(userId int, message string)
}
// UserReporting interface
type UserReporting interface {
GenerateUserReport(userId int)
}
Go<?php
// User.php
interface User {
public function createUser(string $username, string $password);
public function deleteUser(int $userId);
public function updateUser(int $userId, string $username, string $password);
}
// UserNotification.php
interface UserNotification {
public function sendEmailNotification(int $userId, string $subject, string $body);
public function sendSmsNotification(int $userId, string $message);
}
// UserReporting.php
interface UserReporting {
public function generateUserReport(int $userId);
}
PHP// User.ts
interface User {
createUser(username: string, password: string): void;
deleteUser(userId: number): void;
updateUser(userId: number, username: string, password: string): void;
}
// UserNotification.ts
interface UserNotification {
sendEmailNotification(userId: number, subject: string, body: string): void;
sendSmsNotification(userId: number, message: string): void;
}
// UserReporting.ts
interface UserReporting {
generateUserReport(userId: number): void;
}
TypeScript