SOLID Principles

Overview

SOLID stands for the following principles
  1. S - Single Responsibility Principle
  2. O - Open/Closed Principle
  3. L - Liskov Substitution Principle
  4. I - Interface Segregation Principle
  5. D - Dependency Injection Principle

Single Responsibility Principle

A class should serve only one purpose at a time. The class should take only one responsibility in a project or application. A class should have only one job.
 public class Order {
private final int orderId;
private final double amount;
private final String productName;
private final String emailRecipient = "iamraajkanchan@gmail.com";

public Order(int orderId, double amount, String productName) {
this.orderId = orderId;
this.amount = amount;
this.productName = productName;
}

public void showDetails() {
System.out.println("Product Name: " + productName + " ,Amount: " + amount + " ,Order ID: " + orderId);
}

public void sendEmail() {
System.out.println("Sending email to " + emailRecipient);
}
}
 public class MainSingleResponsibility {
public static void main(String[] args) {
Order order1 = new Order(1, 25.25, "Java Book");
order1.showDetails();
order1.sendEmail();
}
}
The above code is a clear violation of Single Responsibility Principle because the class of Order has to deal with the job of sending email which can be separated in a different class.
 public class Email {
public final static String email = "iamraajkanchan@gmail.com";

public static void sendEmail() {
System.out.println("Sending email to " + email);
}
}
 public class Order {
private final int orderId;
private final double amount;
private final String productName;

public Order(int orderId, double amount, String productName) {
this.orderId = orderId;
this.amount = amount;
this.productName = productName;
}

public void showDetails() {
System.out.println("Product Name: " + productName + " ,Amount: " + amount + " ,Order ID: " + orderId);
}
}
 public class MainSingleResponsibility {
public static void main(String[] args) {
Order order1 = new Order(1, 25.25, "Java Book");
order1.showDetails();
Email.sendEmail();
}
}
The above code follows the principle of Single Responsibility Principle.

Open/Closed Principle

A class should be easily extendable without modifying the class itself. Though you can make some changes but try not to modify too much in the class. 
 public class Calculation extends Order {
private double balance = 100.0;
public Calculation(int orderId, double amount, String productName, String customerName) {
super(orderId, amount, productName, customerName);
}

public void printBalance() {
if (balance > amount) {
balance = balance - amount;
System.out.println("Balance of " + customerName + " is " + balance);
} else {
System.out.println("You do not have enough amount in your wallet");
}
}
}
 public class Order {
private final int orderId;
public final double amount;
private final String productName;
public final String customerName;

public Order(int orderId, double amount, String productName, String customerName) {
this.orderId = orderId;
this.amount = amount;
this.productName = productName;
this.customerName = customerName;
}

public double getAmount() {
return amount;
}

public String getCustomerName() {
return customerName;
}

public void showDetails() {
System.out.println("Customer Name: " + customerName + " ,Product Name: " + productName + " ,Amount: " + amount + " ,Order ID: " + orderId);
}
}
 public class Email {
public final static String email = "iamraajkanchan@gmail.com";

public static void sendEmail() {
System.out.println("Sending email to " + email);
}
}
 public class MainSingleResponsibility {
public static void main(String[] args) {
Calculation rajCalculation = new Calculation(1, 25.25, "Java Book", "Raaj Kanchan");
rajCalculation.showDetails();
Email.sendEmail();
rajCalculation.printBalance();
}
}
The above code follows the rule of Open/Closed Principle. 
 public abstract class Shape {
public abstract void area();
}
 public class Square extends Shape {
private final double length;

public Square(double length) {
this.length = length;
}

@Override
public void area() {
System.out.println("Area of Square is " + (4 * length));
}
}
 public class Circle extends Shape {
private final double radius;

public Circle(double radius) {
this.radius = radius;
}

@Override
public void area() {
System.out.println("Area of Circle is " + (Math.PI * radius * radius));
}
}
 public class Rectangle extends Shape {
private final double length;
private final double width;

public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}

@Override
public void area() {
System.out.println("Area of rectangle is " + (length * width));
}
}
 public class AreaCalculator {
static Shape shape;

public static void setShape(Shape shape) {
AreaCalculator.shape = shape;
}

public static void calculate() {
AreaCalculator.shape.area();
}
}
 public class MainOpenClosePrinciple {
public static void main(String[] args) {
AreaCalculator.setShape(new Circle(4.5));
AreaCalculator.calculate();
AreaCalculator.setShape(new Square(4.0));
AreaCalculator.calculate();
AreaCalculator.setShape(new Rectangle(4.0, 5.0));
AreaCalculator.calculate();
}
}
The above code follows the principle of Open/Closed Principle.

Liskov Substitution Principle

Interface Segregation Principle

Dependency Injection Principle

Advantages of SOLID Principle

  1. Using this principle we can avoid writing tightly coupled codes for different modules of an application.
  2. With this principle we can easily accommodate new requirements and features. 
  3. Testing such loosely coupled codes are easier than tightly coupled codes.
  4. This principle prevents redundant codes.
  5. We can identify new bugs if we solve the previous ones.

Reference

Comments