SOLID: I - Interface Segregation Principle (ISP)

Paulo Messias - Aug 21 - - Dev Community

Introduction to ISP:
The Interface Segregation Principle (ISP) is the fourth principle in the SOLID design principles. ISP states that a client should not be forced to implement interfaces it doesn't use. Instead of having one large interface, it's better to have multiple smaller, more specific interfaces. This principle ensures that classes only need to implement methods that are relevant to them, promoting loose coupling and reducing the impact of changes.

Objectives of ISP:

  • Promote Decoupling: Reduces dependencies between classes by ensuring that they only depend on the interfaces they actually use.
  • Enhance Flexibility: Allows different parts of the application to evolve independently by isolating changes to specific interfaces.
  • Improve Code Readability: Smaller, more focused interfaces are easier to understand and implement.
  • Facilitate Maintenance: Simplifies the maintenance of the system by reducing the likelihood of unintended side effects when interfaces change.

Bad Practice Example (Classes):
Here we have a Worker interface that forces all classes to implement methods they may not need.

interface Worker {
  work(): void;
  eat(): void;
}

class HumanWorker implements Worker {
  work(): void {
    // Human working
  }

  eat(): void {
    // Human eating
  }
}

class RobotWorker implements Worker {
  work(): void {
    // Robot working
  }

  eat(): void {
    // Robots don't eat, but must implement this method
  }
}
Enter fullscreen mode Exit fullscreen mode

In this approach, the RobotWorker class is forced to implement the eat method, which is not applicable to robots, violating ISP.

Good Practice Example (Classes):
To follow ISP, we can split the Worker interface into more specific interfaces.

interface Workable {
  work(): void;
}

interface Eatable {
  eat(): void;
}

class HumanWorker implements Workable, Eatable {
  work(): void {
    // Human working
  }

  eat(): void {
    // Human eating
  }
}

class RobotWorker implements Workable {
  work(): void {
    // Robot working
  }
}
Enter fullscreen mode Exit fullscreen mode

Now, the RobotWorker class only implements the Workable interface, adhering to ISP.

Bad Practice Example (Functions):
Consider a function that forces an object to implement more than what it needs.

interface Printer {
  print(): void;
  scan(): void;
  fax(): void;
}

class SimplePrinter implements Printer {
  print(): void {
    // Printing
  }

  scan(): void {
    // Scanning, but not needed
  }

  fax(): void {
    // Faxing, but not needed
  }
}
Enter fullscreen mode Exit fullscreen mode

Here, the SimplePrinter class must implement unnecessary methods (scan and fax), violating ISP.

Good Practice Example (Functions):
To adhere to ISP, we can split the Printer interface into smaller, more focused interfaces.

interface Printable {
  print(): void;
}

interface Scannable {
  scan(): void;
}

interface Faxable {
  fax(): void;
}

class SimplePrinter implements Printable {
  print(): void {
    // Printing
  }
}
Enter fullscreen mode Exit fullscreen mode

With this approach, SimplePrinter only implements the Printable interface, which is all it needs.

Conclusion:
The Interface Segregation Principle encourages developers to create more focused and granular interfaces, ensuring that classes are only required to implement what they actually need. This leads to more modular and maintainable code. By following ISP, you make your applications more flexible and reduce the risk of unintended side effects when interfaces change. In React Native development with TypeScript, applying ISP ensures that components and classes remain loosely coupled and easier to manage as your application grows.

. . . . . . . . . . . . . . . . . . . . . . . .