Discover how simple rules can turn messy code into a smooth-running machine!
Why Applying SOLID to real code in LLD? - Purpose & Use Cases
Imagine building a big software project by writing all code in one giant block without clear rules. When you want to fix a small bug or add a new feature, you have to dig through tangled code, risking breaking other parts.
This manual way is slow because changes affect many places. It's easy to make mistakes since everything is connected tightly. Testing becomes hard, and teamwork slows down as everyone struggles to understand the messy code.
Applying SOLID principles breaks code into clear, simple parts with well-defined roles. Each part does one job and can be changed without breaking others. This makes code easier to read, fix, and grow over time.
class User { void save() { /* save user and send email */ } void sendEmail() { /* email code here */ } }
interface UserRepository { void save(User u); }
interface EmailService { void sendEmail(User u); }
class UserService {
UserRepository repo;
EmailService email;
void register(User u) {
repo.save(u);
email.sendEmail(u);
}
}It enables building software that is easy to change, test, and grow without fear of breaking things.
Think of a delivery app where adding a new payment method or changing how orders are tracked can be done quickly without rewriting the whole system.
SOLID makes code clear and focused.
It reduces bugs and speeds up changes.
Teams can work better together on clean code.
Practice
Solution
Step 1: Understand the principle names
Single Responsibility Principle means one class should do one job only.Step 2: Match principle to description
Only Single Responsibility Principle talks about one reason to change.Final Answer:
Single Responsibility Principle -> Option DQuick Check:
One class, one reason to change = Single Responsibility Principle [OK]
- Confusing Single Responsibility with Open/Closed
- Thinking Dependency Inversion means single responsibility
- Mixing Liskov Substitution with class responsibilities
Solution
Step 1: Identify Dependency Inversion Principle
It says depend on abstractions (interfaces), not concrete classes.Step 2: Check which code uses interfaces
interface Engine { void start(); } class Car { Engine engine; Car(Engine e) { engine = e; } } uses interface Engine and injects it into Car, following DIP.Final Answer:
Interface with injection to depend on abstraction -> Option BQuick Check:
Depend on interface, not concrete class = DIP [OK]
- Creating concrete objects inside classes (violates DIP)
- Extending concrete classes instead of using interfaces
- Not using constructor or setter injection
interface Shape { double area(); }
class Rectangle implements Shape {
double width, height;
Rectangle(double w, double h) { width = w; height = h; }
public double area() { return width * height; }
}
class Circle implements Shape {
double radius;
Circle(double r) { radius = r; }
public double area() { return 3.14 * radius * radius; }
}
class AreaCalculator {
double totalArea(Shape[] shapes) {
double total = 0;
for (Shape s : shapes) total += s.area();
return total;
}
}
public class Main {
public static void main(String[] args) {
Shape[] shapes = { new Rectangle(2,3), new Circle(1) };
System.out.println(new AreaCalculator().totalArea(shapes));
}
}Solution
Step 1: Calculate Rectangle area
Rectangle area = 2 * 3 = 6Step 2: Calculate Circle area
Circle area = 3.14 * 1 * 1 = 3.14Step 3: Sum areas
Total area = 6 + 3.14 = 9.14Final Answer:
9.14 -> Option AQuick Check:
6 + 3.14 = 9.14 [OK]
- Using wrong formula for circle area
- Adding radius instead of area
- Forgetting to sum both shapes
class Report {
void printReport(String type) {
if (type.equals("PDF")) { System.out.println("Printing PDF"); }
else if (type.equals("HTML")) { System.out.println("Printing HTML"); }
}
}Solution
Step 1: Understand Open/Closed Principle
Classes should be open for extension but closed for modification.Step 2: Analyze printReport method
Adding new types means editing if-else, so modifying existing code.Final Answer:
Adding new report types requires changing printReport method -> Option AQuick Check:
Modifying code to add features breaks Open/Closed Principle [OK]
- Thinking if-else is always fine
- Confusing Open/Closed with Single Responsibility
- Ignoring need for polymorphism
Solution
Step 1: Understand Interface Segregation Principle
Clients should not depend on methods they do not use; interfaces should be small and specific.Step 2: Apply to payment system
Separate interfaces for each payment type avoid forcing classes to implement unused methods.Final Answer:
Create separate interfaces like CreditCardPaymentInterface and PayPalPaymentInterface with only relevant methods -> Option CQuick Check:
Small, specific interfaces = Interface Segregation Principle [OK]
- Using one big interface for all payment types
- Inheriting unrelated payment classes
- Using abstract class forcing all methods
Ready to prove it?
Pass the test and this pattern moves unknown
