Interface segregation principle

This principle state that no code should be forced to depend on methods it does not use. It means that if you want to apply ISP, you should split large interfaces into smaller and more specific ones so that object can use only interface they are interested about. It is one of the principle that is more and more used with the rise of microservices architectures.

Code example

Bad implementation
  
from dataclasses import dataclass
from abc import abstractmethod


# Bad implementation
@dataclass
class Atm():
    amount: float

    @abstractmethod
    def deposit(self, amount_deposed: float):
        pass

    @abstractmethod
    def withdrawal(self, amount_withdrawed: float) -> float:
        pass


class AtmBankOne(Atm):

    def deposit(self, amount_deposed: float):
        print(f"{amount_deposed} have been deposed on your bank one account")
        self.amount += amount_deposed

    def withdrawal(self, amount_withdrawed: float) -> float:
        print(f"{amount_withdrawed} have been withdrawed of your bank one account")
        self.amount += amount_withdrawed


class AtmBlockedAccount(Atm):
    """ATM only for deposit

    Args:
        Atm (_type_): Atm interface.
    """

    def deposit(self, amount_deposed: float):
        print(f"{amount_deposed} have been deposed on your blocked account")
        self.amount += amount_deposed


    

  
Good implementation
  

    # Good implementation


    @dataclass
    class Atm():
        amount: float
    
    
    @dataclass
    class AtmDeposit(Atm):
    
        @abstractmethod
        def deposit(self, amount_deposed: float):
            pass
    
    
    @dataclass
    class AtmWithdrawal(Atm):
    
        @abstractmethod
        def withdrawal(self, amount_withdrawed: float) -> float:
            pass
    
    
    class AtmBankOne(AtmDeposit, AtmWithdrawal):
    
        def deposit(self, amount_deposed: float):
            print(f"{amount_deposed} have been deposed on your bank one account")
            self.amount += amount_deposed
    
        def withdrawal(self, amount_withdrawed: float) -> float:
            print(f"{amount_withdrawed} have been withdrawed of your bank one account")
            self.amount += amount_withdrawed
    
    
    class AtmBlockedAccount(AtmDeposit):
        """ATM only for deposit
    
        Args:
            Atm (_type_): Atm interface.
        """
    
        def deposit(self, amount_deposed: float):
            print(f"{amount_deposed} have been deposed on your blocked account")
            self.amount += amount_deposed

  

References

  • https://en.wikipedia.org/wiki/Interface_segregation_principle
  • "Clean Architecture: A Craftsman's Guide to Software Structure and Design" by Robert Martin