Discover how simple rules can turn chaotic code into a well-oiled machine!
Why Object-oriented design principles in LLD? - Purpose & Use Cases
Imagine building a complex software system by writing all code in one big file without any clear structure or rules.
Every time you want to add a feature or fix a bug, you have to search through thousands of lines of tangled code.
This manual approach is slow because changes in one place can break things elsewhere.
It is error-prone since there is no clear separation of responsibilities.
Maintaining and scaling the system becomes a nightmare as the code grows.
Object-oriented design principles guide us to organize code into clear, reusable parts called objects.
These principles help keep code clean, easy to understand, and simple to change without breaking other parts.
function process() { /* all logic mixed here */ }class User { login() { } }It enables building flexible and maintainable software that can grow smoothly as needs change.
Think of a car factory where each worker has a clear job; object-oriented design makes software development just as organized and efficient.
Manual coding without structure leads to messy, fragile systems.
Object-oriented principles bring clarity and order to code.
They make software easier to build, fix, and expand.
Practice
Solution
Step 1: Understand SRP definition
The Single Responsibility Principle states that a class should have only one reason to change, meaning it should focus on a single job or responsibility.Step 2: Evaluate options against SRP
A class should have only one reason to change, meaning it should have only one job. matches this definition exactly. Options A, B, and C describe other concepts or incorrect ideas.Final Answer:
A class should have only one reason to change, meaning it should have only one job. -> Option DQuick Check:
Single Responsibility Principle = One class, one job [OK]
- Confusing SRP with inheritance rules
- Thinking SRP allows multiple unrelated jobs in one class
- Believing tight coupling is good design
Solution
Step 1: Understand Open/Closed Principle (OCP)
OCP means software entities like classes should be open for extension but closed for modification. This means you can add new behavior by extending classes without changing existing code.Step 2: Analyze options for OCP compliance
class Shape { void draw() {} } class Circle extends Shape { void draw() { /* draw circle */ } } shows a base class Shape and a subclass Circle that extends Shape and overrides draw(), adding new behavior without modifying Shape. This follows OCP. class Shape { void draw() {} } class Circle { void draw() { /* draw circle */ } } lacks inheritance, so no extension. class Shape { void draw() {} } class Circle extends Shape { void draw() { super.draw(); } } calls super.draw() but does not add new behavior. class Shape { void draw() {} } class Circle extends Shape { void draw() { /* draw circle */ } } class Square extends Circle {} extends Circle with Square, which is allowed but less clear and may break OCP if Square changes Circle behavior.Final Answer:
class Shape { void draw() {} } class Circle extends Shape { void draw() { /* draw circle */ } } -> Option BQuick Check:
Open/Closed = Extend by subclassing, no base change [OK]
- Ignoring inheritance for extension
- Modifying base class instead of extending
- Confusing method overriding with no added behavior
class Bird:
def fly(self):
return "Flying"
class Penguin(Bird):
def fly(self):
return "Cannot fly"
bird = Bird()
penguin = Penguin()
print(bird.fly())
print(penguin.fly())What is the output of this code?
Solution
Step 1: Understand code behavior
Bird class has fly() returning "Flying". Penguin inherits Bird but overrides fly() to return "Cannot fly". bird.fly() prints "Flying". penguin.fly() prints "Cannot fly".Step 2: Predict output lines
First print outputs "Flying". Second print outputs "Cannot fly" as per Penguin's override.Final Answer:
"Flying" followed by "Cannot fly" -> Option AQuick Check:
Subclass override changes output correctly [OK]
- Assuming subclass must behave exactly like parent
- Expecting runtime error for overridden method
- Confusing method override with inheritance
class LightBulb {
void turnOn() { System.out.println("Light on"); }
void turnOff() { System.out.println("Light off"); }
}
class Switch {
private LightBulb bulb = new LightBulb();
void operate(boolean on) {
if(on) bulb.turnOn();
else bulb.turnOff();
}
}Solution
Step 1: Understand Dependency Inversion Principle (DIP)
DIP states that high-level modules should not depend on low-level modules directly; both should depend on abstractions (interfaces or abstract classes).Step 2: Analyze code for DIP violation
Switch class creates and uses a concrete LightBulb instance directly, tightly coupling Switch to LightBulb. This violates DIP because Switch depends on a concrete class, not an abstraction.Final Answer:
Switch class directly depends on concrete LightBulb class instead of an abstraction. -> Option CQuick Check:
DIP = Depend on abstractions, not concrete classes [OK]
- Thinking methods in LightBulb are wrong
- Believing multiple instances are needed
- Confusing inheritance with dependency
Solution
Step 1: Identify the need for extensibility
The system must allow adding new payment methods without modifying existing code, which is a classic use case for the Open/Closed Principle (OCP).Step 2: Apply OCP with interface and implementations
Define a Payment interface with common methods. Implement each payment method (credit card, PayPal, crypto) as separate classes implementing this interface. This allows adding new methods by creating new classes without changing existing ones.Final Answer:
Use the Open/Closed Principle by defining a Payment interface and implementing new payment classes for each method. -> Option AQuick Check:
OCP = Add new classes, no existing code change [OK]
- Putting all logic in one class violating SRP
- Confusing inheritance with extensibility
- Depending on concrete classes instead of abstractions
Ready to prove it?
Pass the test and this pattern moves unknown
