Discover how simple patterns can save you from tangled, hard-to-change code!
Why Behavioral patterns (Observer, Strategy, Command) in Software Engineering? - Purpose & Use Cases
Imagine you are building a software system where many parts need to react to changes in one part, or where you want to switch how a task is done without changing the whole program. Doing this by hand means writing lots of repeated code and tangled logic everywhere.
Manually updating every part that depends on a change is slow and error-prone. Changing how a task works means rewriting big chunks of code, risking bugs. The code becomes hard to read, maintain, and extend, making future updates a nightmare.
Behavioral patterns like Observer, Strategy, and Command organize how objects communicate and change behavior. They let you separate concerns, react automatically to changes, and swap behaviors easily without rewriting code, making your software flexible and easier to manage.
if (event) { updatePartA(); updatePartB(); updatePartC(); } // repeated everywhere if (taskType == 1) { doTaskA(); } else if (taskType == 2) { doTaskB(); }
subject.attach(observerA); subject.attach(observerB); subject.notify(); strategy = new ConcreteStrategyA(); context.setStrategy(strategy); context.executeStrategy();
It enables building software that adapts smoothly to change, reacts automatically to events, and keeps code clean and easy to update.
Think of a news app where users get notified instantly when new articles arrive (Observer), can choose how to sort articles (Strategy), and can queue actions like saving or sharing articles (Command) without changing the app's core.
Behavioral patterns help manage communication and behavior changes in software.
They reduce repeated code and make programs easier to maintain.
Using these patterns leads to flexible, scalable, and clean software design.
Practice
Solution
Step 1: Understand the role of Observer pattern
The Observer pattern allows one object (the subject) to notify many dependent objects (observers) automatically when its state changes.Step 2: Compare with other patterns
Strategy selects algorithms at runtime, Command encapsulates requests, and Singleton restricts instance creation. Only Observer fits the notification role.Final Answer:
Observer -> Option CQuick Check:
Notification to many = Observer [OK]
- Confusing Strategy with Observer
- Thinking Command handles notifications
- Mixing Singleton with behavioral patterns
Solution
Step 1: Identify Command pattern structure
The Command pattern encapsulates a request as an object, typically by defining an interface with anexecute()method to perform the action.Step 2: Eliminate other options
A class that holds multiple algorithms to choose from describes Strategy, C describes Observer, and D describes Singleton, none of which define a command interface.Final Answer:
An interface with a method like execute() to perform the action -> Option AQuick Check:
Command interface = execute() method [OK]
- Confusing Command with Strategy interface
- Thinking Command notifies observers
- Mixing Singleton with Command
class Context:
def __init__(self, strategy):
self.strategy = strategy
def execute(self, data):
return self.strategy.do_algorithm(data)
class StrategyA:
def do_algorithm(self, data):
return sorted(data)
class StrategyB:
def do_algorithm(self, data):
return sorted(data, reverse=True)
context = Context(StrategyA())
result = context.execute([3, 1, 2])
print(result)What will be the output?
Solution
Step 1: Understand the Strategy pattern usage
The Context uses StrategyA, whosedo_algorithmmethod sorts the list in ascending order.Step 2: Trace the execution
Callingcontext.execute([3, 1, 2])callsStrategyA.do_algorithmwhich returns[1, 2, 3].Final Answer:
[1, 2, 3] -> Option BQuick Check:
StrategyA sorts ascending = [1, 2, 3] [OK]
- Assuming StrategyB is used
- Confusing sorting order
- Expecting original list unchanged
Solution
Step 1: Understand observer detachment importance
If observers are not detached, the subject keeps references to them, preventing garbage collection.Step 2: Identify consequence
This causes memory leaks because unused observers remain in memory unnecessarily.Final Answer:
Memory leaks due to lingering references -> Option AQuick Check:
Undetached observers cause memory leaks [OK]
- Confusing with Strategy or Command issues
- Thinking it causes command execution failure
- Assuming Singleton duplication
Solution
Step 1: Analyze the requirement for queuing and undo
Queuing operations and supporting undo requires encapsulating each request as an object to store and manage them flexibly.Step 2: Match with behavioral patterns
The Command pattern encapsulates requests as objects, enabling queuing, logging, and undo functionality. Observer and Strategy do not support queuing commands, and Singleton only controls instance creation.Final Answer:
Command pattern, because it encapsulates requests as objects allowing queuing and undo -> Option DQuick Check:
Queue and undo operations = Command pattern [OK]
- Choosing Observer for queuing commands
- Confusing Strategy with Command
- Selecting Singleton for operation management
Ready to prove it?
Pass the test and this pattern moves unknown
