SOLID principles in Software Engineering - Time & Space Complexity
We want to understand how the SOLID principles affect the time it takes for software to run.
Specifically, how following these principles changes the work done as programs grow.
Analyze the time complexity of a class that violates the Single Responsibility Principle.
class OrderProcessor:
def __init__(self, order):
self.order = order
def calculate_total(self):
total = 0
for item in self.order.items:
total += item.price * item.quantity
return total
def save_order(self):
database.save(self.order)
This class handles order calculation and saving, mixing responsibilities.
Look at loops and repeated work in the code.
- Primary operation: Looping through all items in the order to calculate total.
- How many times: Once per item in the order.
The time to calculate the total grows as the number of items grows.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 additions and multiplications |
| 100 | 100 additions and multiplications |
| 1000 | 1000 additions and multiplications |
Pattern observation: The work grows directly with the number of items.
Time Complexity: O(n)
This means the time to calculate grows in a straight line as the order gets bigger.
[X] Wrong: "Mixing responsibilities in one class makes the program faster."
[OK] Correct: Combining tasks can make code harder to maintain and can hide costly operations, not necessarily faster.
Understanding how SOLID principles affect code structure and performance shows you can write clear and efficient programs.
"What if we split the class so each handles only one task? How would that affect the time complexity?"
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 have one job or responsibility.Step 2: Evaluate options
A class should have only one reason to change.: A class should have only one reason to change. matches this definition exactly. Options B, C, and D contradict the principle by suggesting multiple responsibilities or tight coupling.Final Answer:
A class should have only one reason to change. -> Option AQuick Check:
SRP = One responsibility [OK]
- Thinking SRP allows multiple responsibilities
- Confusing SRP with inheritance rules
- Believing tight coupling is allowed
Solution
Step 1: Recall OCP definition
The Open/Closed Principle states that software entities should be open for extension but closed for modification, meaning you can add new features without changing existing code.Step 2: Match options to definition
Software entities should be open for extension but closed for modification.: Software entities should be open for extension but closed for modification. correctly states this principle. Software entities should be open for modification but closed for extension. reverses the terms, and options B and D contradict the principle.Final Answer:
Software entities should be open for extension but closed for modification. -> Option DQuick Check:
OCP = Open extension, closed modification [OK]
- Mixing up 'open for extension' and 'open for modification'
- Thinking OCP allows changing existing code freely
- Confusing OCP with SRP
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: Analyze Bird and Penguin classes
Bird has a fly method returning "Flying". Penguin overrides fly to return "Cannot fly".Step 2: Check print statements output
bird.fly() returns "Flying". penguin.fly() returns "Cannot fly". So output is two lines: "Flying" then "Cannot fly".Final Answer:
"Flying" followed by "Cannot fly" -> Option AQuick Check:
bird.fly() = Flying, penguin.fly() = Cannot fly [OK]
- Assuming penguin.fly() returns "Flying"
- Expecting runtime error from override
- Confusing method outputs order
class WorkerInterface:
def work(self): pass
def eat(self): pass
class Robot(WorkerInterface):
def work(self):
print("Working")
def eat(self):
raise Exception("Robots don't eat")Solution
Step 1: Understand ISP
Interface Segregation Principle says clients should not be forced to depend on methods they do not use.Step 2: Analyze Robot class
Robot implements eat() but raises an exception because it doesn't eat. This violates ISP because Robot is forced to implement an irrelevant method.Final Answer:
Robot class should not implement eat() if it doesn't apply. -> Option CQuick Check:
ISP forbids unused methods in interfaces [OK]
- Thinking raising exception is acceptable
- Believing interface must have only one method
- Assuming no error if code runs
Solution
Step 1: Identify the problem
The system needs to add new payment methods often without modifying existing code.Step 2: Match with SOLID principles
The Open/Closed Principle states software should be open for extension but closed for modification, exactly fitting this need.Final Answer:
Open/Closed Principle -> Option BQuick Check:
OCP = Add features without changing old code [OK]
- Confusing SRP with OCP
- Thinking LSP controls adding new types
- Assuming Dependency Inversion solves this
Ready to prove it?
Pass the test and this pattern moves unknown
