5 Golden Rules to Improve Code Quality in Java: SOLID Principles

SOLID refers to five fundamental principles used in software design. These principles ensure that software is more flexible, maintainable, and testable. The SOLID principles are as follows: S: Single Responsibility Principle (SRP): A class should have only one responsibility. It ensures that classes are more understandable and manageable. public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void createUser(String name) { userRepository.save(name); } } O: Open/Closed Principle (OCP): Classes should be open for extension but closed for modification. It allows you to add new functionality without changing existing code. public interface Shape { double area(); } public class Circle implements Shape { private final double radius; public Circle(double radius) { this.radius = radius; } @Override public double area() { return Math.PI * radius * radius; } } public class Rectangle implements Shape { private final double width; private final double height; public Rectangle(double width, double height) { this.width = width; this.height = height; } @Override public double area() { return width * height; } } L: Liskov Substitution Principle (LSP): Derived classes should be substitutable for their base classes. It ensures that objects can be used interchangeably. abstract class FlyingBird{ abstract void fly(); } abstract class NonFlyingBird{ abstract void doSomething(); } class Eagle extends FlyingBird { @Override public void fly() { // implement something } } class Ostrich extends NonFlyingBird { @Override public void doSomething() { // implement something } } I: Interface Segregation Principle (ISP): Users should not be forced to depend on interfaces they do not use. It ensures that interfaces are more specific and understandable. interface IAreaCalculator { double calculateArea(); } interface IVolumeCalculator { double calculateVolume(); } class Square implements IAreaCalculator { @Override public double calculateArea() { // calculate the area } } class Cube implements IAreaCalculator, IVolumeCalculator { @Override public double calculateArea() { // calculate the area } @Override public double calculateVolume() { // calculate the volume } } D: Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions. This reduces dependencies and increases testability. class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void createUser(String name) { userRepository.save(name); } } class CourseService { private final UserService userService; public CourseService(UserService userService) { this.userService = userService; } public void createCourse(String name) { // implementation } } Keyword Description Coupling The degree of interdependence between software modules. Low coupling is preferred for modularity and maintainability. Cohesion The degree to which the elements of a module belong together. High cohesion is desired for clarity and focus. Single Responsibility Principle (SRP) A class should have only one responsibility. It ensures that classes are more understandable and manageable. Open/Closed Principle (OCP) Classes should be open for extension but closed for modification. It allows adding new functionality without changing existing code. Liskov Substitution Principle (LSP) Derived classes should be substitutable for their base classes. It ensures objects can be used interchangeably. Interface Segregation Principle (ISP) Users should not be forced to depend on interfaces they do not use. It ensures interfaces are more specific and understandable. Dependency Inversion Principle (DIP) High-level modules should not depend on low-level modules. Both should depend on abstractions. This reduces dependencies and increases testability. Thank you for your interest in the SOLID principles! For more insights and resources, feel free to check out https://dub.sh/burakboduroglu.

Mar 26, 2025 - 16:41
 0
5 Golden Rules to Improve Code Quality in Java: SOLID Principles

SOLID refers to five fundamental principles used in software design. These principles ensure that software is more flexible, maintainable, and testable.

The SOLID principles are as follows:

S: Single Responsibility Principle (SRP): A class should have only one responsibility. It ensures that classes are more understandable and manageable.

public class UserService {
  private final UserRepository userRepository;

  public UserService(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  public void createUser(String name) {
    userRepository.save(name);
  }
}

O: Open/Closed Principle (OCP): Classes should be open for extension but closed for modification. It allows you to add new functionality without changing existing code.

public interface Shape {
  double area();
}

public class Circle implements Shape {
  private final double radius;

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

  @Override
  public double area() {
    return Math.PI * radius * radius;
  }
}

public class Rectangle implements Shape {
  private final double width;
  private final double height;

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

  @Override
  public double area() {
    return width * height;
  }
}

L: Liskov Substitution Principle (LSP): Derived classes should be substitutable for their base classes. It ensures that objects can be used interchangeably.

abstract class FlyingBird{
  abstract void fly();
}

abstract class NonFlyingBird{
  abstract void doSomething();
}

class Eagle extends FlyingBird {
  @Override
  public void fly() {
  // implement something
  }
}

class Ostrich extends NonFlyingBird {
  @Override
  public void doSomething() {
  // implement something
  }
}

I: Interface Segregation Principle (ISP): Users should not be forced to depend on interfaces they do not use. It ensures that interfaces are more specific and understandable.

interface IAreaCalculator {
  double calculateArea();
}

interface IVolumeCalculator {
  double calculateVolume();
}

class Square implements IAreaCalculator {
  @Override
  public double calculateArea() {
   // calculate the area
  }
}

class Cube implements IAreaCalculator, IVolumeCalculator {
  @Override
  public double calculateArea() {
   // calculate the area
  }

  @Override
  public double calculateVolume() {
   // calculate the volume
  }
}

D: Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions. This reduces dependencies and increases testability.

class UserService {
   private final UserRepository userRepository;

   public UserService(UserRepository userRepository) {
     this.userRepository = userRepository;
   }

   public void createUser(String name) {
     userRepository.save(name);
   }
 }

class CourseService {
   private final UserService userService;

   public CourseService(UserService userService) {
     this.userService = userService;
   }

   public void createCourse(String name) {
     // implementation
   }
 }
Keyword Description
Coupling The degree of interdependence between software modules. Low coupling is preferred for modularity and maintainability.
Cohesion The degree to which the elements of a module belong together. High cohesion is desired for clarity and focus.
Single Responsibility Principle (SRP) A class should have only one responsibility. It ensures that classes are more understandable and manageable.
Open/Closed Principle (OCP) Classes should be open for extension but closed for modification. It allows adding new functionality without changing existing code.
Liskov Substitution Principle (LSP) Derived classes should be substitutable for their base classes. It ensures objects can be used interchangeably.
Interface Segregation Principle (ISP) Users should not be forced to depend on interfaces they do not use. It ensures interfaces are more specific and understandable.
Dependency Inversion Principle (DIP) High-level modules should not depend on low-level modules. Both should depend on abstractions. This reduces dependencies and increases testability.

Thank you for your interest in the SOLID principles! For more insights and resources, feel free to check out https://dub.sh/burakboduroglu.