SOLID
S: Single Responsibility Principle
- There should never be more than one reason for a class to change.
- In other words, every class should have only one responsibility.
O: Open Closed Principle
Openfor extension andClosedfor modification- a software entity (class, module, function) should be open for extension but closed for modification.
- Example:
- This can be achieved through abstraction, i.e., by creating interfaces
- We can write implementation when it is needed
L: Liskov’s Substitution Principle
- It states that subclasses should be substitutable for their base classes.
- A client using a base class should continue to function properly even if a derived class is passed to it.
- It is possible to have array of different child classes
class Animal {}
class Cat extends Animal {}
class Dog extends Animal {}
class Squirrel extends Animal {}
// Array of different child classes
List<Animal> animals = List.of(new Cat(), new Dog(), new Squirrel());I: Interface Segregation Principle
- Many client-specific interfaces are better than one general-purpose interface.
- An interface should be dependent more on the code that calls it rather than the code that implements it.
- Suppose you are implementing an interface then you should use all the methods, otherwise create a new interface
- Example:
In the following example
RestaurantEmployeehas unnecessary methods forWaiter. Hence a new interface is needed!
interface RestaurantEmployee
{
void washDishes();
void serveCustomers();
void cookFood();
}
class Waiter implements RestaurantEmployee
{
public void washDishes() {
// This is unnecessary to implement!
}
public void serveCustomers() {
// serving implementation
}
public void cookFood() {
// This is unnecessary to implement!
}
}This is correct way:
interface WaiterInterface
{
void serveCustomers();
}
class Waiter implements WaiterInterface
{
public void serveCustomers() {
// serving implementation
}
}D: Dependency Inversion Principle
- Classes should depend on interfaces of other classes instead of the concrete implementations.
- Without Dependency Inversion, code is difficult to manage, change and test
- Writing Unit tests are easy of dependency inversion principle is followed
- Example:
- Interface:
Keyboardwith following implementation:WiredKeyboardMouseKeyboard
- Interface:
class Macbook
{
// private final WiredKeyboard keyboard; // wrong!
private final Keyboard keyboard; // correct! using interface!
public Macbook() {
keyboard = new WiredKeyboard();
}
}