SOLID Principles in Java

SOLID Principles in Java

Thanks TO : https://medium.com/nerd-for-tech/solid-principles-in-java-5cf926e44247


SOLID principles basically form the fundamental guidelines for building object-oriented, loosely coupled, robust, maintainable, and easily understandable applications. One of the most frequently asked interview questions, let's look at each one of them:

Single Responsibility: A class should have one and only one responsibility. We should write, change or maintain a class for only one purpose which gives us the advantage of cleaner, robust code and fewer test cases as to we know which functionality is covered in which class and which class would be modified in case of a change. For ex:

public class Vehicle{

public void printDetails() {}

public double calculate() {}

public void addtoDB() {}

}

The above class has three separate responsibilities: printing, calculation, and adding to the database. By applying SRP, we can separate the above class into three classes with separate responsibilities.

Open Closed?: A class should be open for extension but closed for modification which essentially means we do not want our existing code to be modified causing potential issues or bugs . Other developers incase of some functionality change should be able to extend our class and override some methods. For ex:

public class VehiclePrice {

public double Value(Vehicle v) {

if (v instanceof Car) {

return v.getValue() * 0.5;

if (v instanceof Truck) {

return v.getValue() * 0.8;

}

}

If we want to add one more type to this, say e-bike, we would have to modify the above class with one more if statement which goes against the principle. A better way is to let the subclasses override the Value method as per their type.

Liskov Substitution: Derived classes must be substitutable for the base class. In simple words, If class A is extending class B, we should be able to replace B with A, without disrupting the behavior of our program. As per OOPS concepts inheritance is a good practice but the Liskov principle mandates to use of inheritance with careful consideration. We should only use inheritance if our superclass is replaceable with a subclass in all the instances.

For ex: Classic Square Rectangle problem.

public class Rectangle {

private double height;

private double width;

public void setHeight(double h) { height = h; }

public void setWidht(double w) { width = w; }

//getters and calculateArea method

}

public class Square extends Rectangle {

public void setHeight(double h) {

super.setHeight(h);

super.setWidth(w);

}

public void setWidth(double h) {

super.setHeight(h);

super.setWidth(w);

}

}

As its clear base class Rectangle is clearly not replaceable by subclass Square, as the square has a constraint of equal height and width, so substituting Rectangle class with Square class breaks LSP.

Interface Segregation: No one should be required to implement methods in their classes that they will not use. Larger interfaces should be split into smaller ones. This ensures that implementing classes only need to be concerned about the methods that are useful to them. This gives us the flexibility to use only the required functionality. For ex:

public interface Vehicle {

public void drive();

public void stop();

public void openDoors();

}

public class Bike implements Vehicle {

// Can be implemented

public void drive() {...}

public void stop() {...}

// Can not be implemented

public void openDoors() {...}

}

For a bike class to implement the openDoors method does not make sense. This should be fixed by breaking the Vehicle interface into multiple smaller interfaces with likely functionality so that no class is forced to implement non-required methods.

Dependency Inversions?: A class should depend on abstraction(interfaces and abstract classes) and not on concretion (classes).

public class Car {

private Engine engine;

public Car(Engine e) {

engine = e;

}

public void start() {

engine.start();

}

}

public class Engine {

public void start() { //some implementation }

}

The above code will work for one engine but what if there are two types of engine, say diesel and petrol, it would mean modifying our class which is not a good idea.

This can be solved by adding an abstraction layer, so the car instead of directly depending on Engine now depends on EngineInterface. PetrolEngine or DieselEngine classes implement this interface and we can connect any of these to the Car class:

Hope this article gives a good idea of SOLID principles. Happy Learning :)

Harish Vagjiyani

PMP | Scrum Master | Project Manager | Web & Mobile Solution Technical Architecture | Lead Developer | DevOps Server Engineer | IT Consultant

2 年

Thanks, Omar same as looking for design patterns

回复
Buddhi Sagar Tiwari

Camunda | Microservices | Java | Azure | Spring Boot | BPM | Ltimindtree | ex-TCSer

2 年

??

回复

要查看或添加评论,请登录

Omar Ismail的更多文章

社区洞察

其他会员也浏览了