DEV Community

Cover image for 5 Golden Rules to Improve Code Quality in Java: SOLID Principles
Burak Boduroğlu
Burak Boduroğlu

Posted on

1 1 1 2 1

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);
  }
}
Enter fullscreen mode Exit fullscreen mode

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;
  }
}
Enter fullscreen mode Exit fullscreen mode

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
  }
}
Enter fullscreen mode Exit fullscreen mode

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
  }
}
Enter fullscreen mode Exit fullscreen mode

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
   }
 }
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed
  • 2:34 --only-changed
  • 4:27 --repeat-each
  • 5:15 --forbid-only
  • 5:51 --ui --headed --workers 1

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay