Site icon

Interface segregation design principle in java (SOLID & real time example)

Let us understand the Interface segregation principle with the help of examples.

1. Example: Interface segregation principle in java

Suppose, we would like to design the calculator display. The calculator can be used any of three different form.

  1. Basic Calculator containing basic mathematical functions like addition, subtraction, multiplication etc
  2. Progrmmers Calculator containing functions like hex to decimal, decimal to binary etc. in addition to basic functions
  3. Scientific Calculator containing functions sin, cos, atan etc in addition to basic functions

We designed a CalculatorDisplay inteface, which caters required functionality of basic, programmer & scientific display. At first glance everything seems okay as CalculatorDisplay is providing the three views for different type of calculators.

2. Program: Application code violating ISP design principle (example)

2.1.) CalculatorDisplay Interface:

package org.learn.without.isp;

public interface CalculatorDisplay {	
	void basicView();
	void programmerView();
	void scientificView();
}

2.2.) BasicCalculator Class:

Fig 1: BasicCalculator Class
package org.learn.without.isp;

import org.apache.commons.lang3.NotImplementedException;

public class BasicCalculator implements CalculatorDisplay {

	@Override
	public void basicView() {
		System.out.println("BasicCalculator: Implemented basic view");
	}

	@Override
	public void programmerView() {
		throw new NotImplementedException("BasicCalculator: programmerView not implemented");
		
	}

	@Override
	public void scientificView() {
		throw new NotImplementedException("BasicCalculator: scientificView not implemented");
	}
}

2.3.) ScientificCalculator Class:

Fig 2: ScientificCalculator Class
package org.learn.without.isp;

import org.apache.commons.lang3.NotImplementedException;

public class ScientificCalculator implements CalculatorDisplay {

	@Override
	public void basicView() {
		System.out.println("ScientificCalculator: implemented basic view");
	}

	@Override
	public void scientificView() {
		System.out.println("ScientificCalculator: implemented scientific view");
	}

	@Override
	public void programmerView() {
		throw new NotImplementedException("ScientificCalculator:programmerView not implemented");
	}
}

2.4.) ProgrammerCalculator Class:

Fig 3: ProgrammerCalculator Class
package org.learn.without.isp;

import org.apache.commons.lang3.NotImplementedException;

public class ProgrammerCalculator implements CalculatorDisplay {

	@Override
	public void basicView() {
		System.out.println("ProgrammerCalculator: implemented basic view");
	}

	@Override
	public void programmerView() {
		System.out.println("ProgrammerCalculator: implemented programmer view");
	}

	@Override
	public void scientificView() {
		throw new NotImplementedException("ProgrammerCalculator:scientificView not implemented");
	}
}

3. Issues with existing design:

We should revisit our current design approach of CalculatorDisplay. CalculatorDisplay interface seems to contain many interfaces and which are not cohesive. Robert C Martin calls them the ‘fat’ or ‘polluted’ interfaces. These ‘fat’ interfaces introduce unwanted dependencies in the classes e.g. BasicCalculator, ScientificCalculator classes etc. What is the right way to define the interfaces?

4. Application code after moving non-cohesive interfaces (ISP compliant)

4.1.) Redesigned or Cohesive Interfaces: 

package org.learn.isp;

public interface BasicDisplay {
	void basicView();
};


package org.learn.isp;

public interface ScientificDisplay {
	void scientificView();
};


package org.learn.isp;

public interface ProgrammerDisplay {

	void programmerView();
};

What we have achieved from above segregation?

4.2.) BasicCalculator Class: 

Fig 4: BasicCalculator Class
package org.learn.isp;

public class BasicCalculator implements BasicDisplay {

	@Override
	public void basicView() {
		System.out.println("BasicCalculator: implemented basic view");
	}
}

4.3.) ScientificCalculator Class:

Fig 5: ScientificCalculator Class
package org.learn.isp;

public class ScientificCalculator implements ScientificDisplay,BasicDisplay {

	@Override
	public void basicView() {
		System.out.println("ScientificCalculator: implemented basic view");
	}
	@Override
	public void scientificView() {
		System.out.println("ScientificCalculator: implemented scientific view");
	}
}

4.4.) ProgrammerCalculator Class:

Fig 6: ProgrammerCalculator Class
package org.learn.isp;

public class ProgrammerCalculator implements ProgrammerDisplay, BasicDisplay {

	@Override
	public void basicView() {
		System.out.println("ProgrammerCalculator: implemented basic view");
	}

	@Override
	public void programmerView() {
		System.out.println("ProgrammerCalculator: implemented programmer view");
	}
}

5. Conclusion:

Download example-Interface segregation design principle

 

Exit mobile version