Interface Segregation Principle

The Interface Segregation Principle states that interfaces should be small and specific. So that classes do not implement methods that they do not need. This principle has in particular the task of eliminating bulky, unnecessarily complex interfaces. Each interface in accordance with this principle should be divided into smaller groups of methods. The program presented below for a coffee machine breaks the ISP principle. One CoffeeMaker interface contains methods that are not entirely used by all classes implementing this interface. Preparing Americano coffee does not require methods such as addMilk() and addFrothyMilk(). Similarly preparation of LatteMacchiato coffee does not require the addWater() method. However, preparation of both coffees requires prepareEspresso() and spendCup() methods. Using one complex interface means that each of the classes implementing the interface must implement all interface methods. Even those that are not needed. The best solution for this case will be to divide one complex interface into several smaller ones. The Americano and LatteMacchiato classes will implement one common interface containing the prepareEspresso() and spendCup() methods. In addition, each class will implement one specific interface. In the Americano class it will be AmericanoPreparing interface, and in LatteMacchiato class it will be the LatteMacchiatoPreparing interface.
interface CoffeeMaker { public function prepareEspresso(); public function addWater(); public function addMilk(); public function addFrothyMilk(); public function spendCup(); } class LatteMacchiato implements CoffeeMaker { public function prepareEspresso() { echo 'Brewing coffee...<br />'; } public function addWater() { } public function addMilk() { echo 'Adding milk...<br />'; } public function addFrothyMilk() { echo 'Adding frothy milk...<br />'; } public function spendCup() { echo 'Coffee is ready! Pick up the cup...<br />'; } } class Americano implements CoffeeMaker { public function prepareEspresso() { echo 'Brewing coffee...<br />'; } public function addWater() { echo 'Adding hot water...<br />'; } public function addMilk() { } public function addFrothyMilk() { } public function spendCup() { echo 'Coffee is ready! Pick up the cup...<br />'; } } $order = new LatteMacchiato(); $order -> prepareEspresso(); $order -> addWater(); $order -> addMilk(); $order -> addFrothyMilk(); $order -> spendCup();
Improved and compatible with the ISP rule source code for the program that supports the coffee machine looks as follows:
interface CoffeeMaker { public function prepareEspresso(); public function spendCup(); } interface LatteMacchiatoPreparing { public function addMilk(); public function addFrothyMilk(); } interface AmericanoPreparing { public function addWater(); } class LatteMacchiato implements CoffeeMaker, LatteMacchiatoPreparing { public function prepareEspresso() { echo 'Brewing coffee...<br />'; } public function addMilk() { echo 'Adding milk...<br />'; } public function addFrothyMilk() { echo 'Adding frothy milk...<br />'; } public function spendCup() { echo 'Coffee is ready! Pick up the cup...<br />'; } } class Americano implements CoffeeMaker, AmericanoPreparing { public function prepareEspresso() { echo 'Brewing coffee...<br />'; } public function addWater() { echo 'Adding hot water...<br />'; } public function spendCup() { echo 'Coffee is ready! Pick up the cup...<br />'; } } $order = new Americano(); $order -> prepareEspresso(); $order -> addWater(); $order -> spendCup();