In this blog, we would discuss what the SOLID design principles are in the context of our chosen programming language Java.
SOLID stands for the following:
- Single Responsibility Principle
A class should only have a single responsibility meaning it should have only one functional reason to change.
Bad Example:
- In the below example, Employee class is supposed to have methods and variables related to employee,
- however the class does more than 1 thing which is it prints the Org Name. It clearly violates the rule of SRP.
public class Employee {
private String empCode;
private String empName;
private LocalDate joiningDate;
public String getEmpCode() { return empCode; }
public String getEmpName() {return empName;}
public LocalDate getJoiningDate() {return joiningDate;}
public void setEmpCode(String code) {this.empCode = code;}
public void setEmpName(String name) {this.empName = name;}
public void setJoiningDate(LocalDate date) {this.joiningDate = date;}
public void printOrgName() { System.out.println("XXXX");}
}
- Open/Closed Principle
"Software entities should be open for extension but closed for modification."
- Liskov Substitution Principle
"Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program." At its heart LSP is about interfaces and contracts as well as how to decide when to extend a class vs. use another strategy such as composition to achieve your goal.
Bad Example:
- In the below example, ThreeDimension class extends the TwoDimension class,
- however the derived class alters the behavior of the base class by introducing one more parameter. It clearly violates the rule of LISP.
public class TwoDimension {
private String height;
private String width;
…
public void addHeight (int x, int y) {… }
public void addWidth (int x, int y) { … }
} }
public class ThreeDimension extends TwoDimension {
public void addHeight (int x, int y, int z) {… }
public void addWidth (int x, int y, int z) { … }
}
- Interface Segregation Principle
"Many client-specific interfaces are better than one general-purpose interface." meaning clients should not be forced to depend on interfaces they do not use. https://www.oodesign.com/interface-segregation-principle.html gives a good example.
- Dependency Inversion Principle
One should "depend upon abstractions, [not] concretions." This says high level modules should not depend on low level modules. Both should depend upon abstractions (interfaces) and be implemented through dependency injection. https://www.tutorialsteacher.com/ioc/dependency-inversion-principle gives a good example.