Practice
Solution
Step 1: Identify encapsulation flow
Private fields cannot be accessed directly; setters provide controlled access.Step 2: Follow setter method process
Setter receives input, validates it, updates the private field, then returns control.Step 3: Analyze incorrect options
The client directly modifies the private field without any method call violates data hiding. The getter method is called first to check the current value before updating misuses getter before setter. The private field is copied to a public variable which the client modifies breaks encapsulation by exposing private data.Final Answer:
Option C -> Option CQuick Check:
Setters control updates with validation, preserving encapsulation.
- Assuming direct field access through setters
- Confusing getter and setter roles
- Thinking private data is copied out for modification
Solution
Step 1: Analyze cost() method
cost() calls self.cost() recursively, causing infinite recursion instead of delegating to wrapped object.Step 2: Identify correct delegation
Should call super().cost() to delegate to wrapped coffee object's cost method.Final Answer:
Option A -> Option AQuick Check:
Recursive call causes stack overflow, breaking decorator chain [OK]
- Calling self.cost() instead of super().cost() in decorators
- Forgetting to delegate calls properly
class PaymentProcessor:
def __init__(self, strategy: PaymentStrategy):
self.strategy = strategy
def pay(self, amount):
if isinstance(self.strategy, CreditCardStrategy):
print(f"Processing credit card payment of ${amount}")
elif isinstance(self.strategy, UPIStrategy):
print(f"Processing UPI payment of ${amount}")
else:
print("Invalid payment method")
Solution
Step 1: Analyze the pay method implementation
The pay method usesisinstancechecks and conditionals to decide behavior, which defeats the purpose of polymorphism.Step 2: Identify correct polymorphic usage
The correct approach is to callself.strategy.pay(amount)directly, letting each strategy handle its own payment logic.Final Answer:
Option A -> Option AQuick Check:
Using conditionals in pay() breaks the strategy pattern [OK]
- Using type checks instead of polymorphism
Solution
Step 1: Identify extensibility needs
Pricing rules vary by multiple factors and may change frequently.Step 2: Evaluate design options
Embedding logic in ParkingSpot or ParkingLot leads to rigid, hard-to-maintain code. Subclass explosion is unmanageable.Step 3: Recognize Strategy pattern benefits
Strategy encapsulates pricing algorithms, allowing dynamic assignment and easy extension without modifying existing classes.Final Answer:
Option A -> Option AQuick Check:
Strategy pattern supports flexible, maintainable pricing logic [OK]
- Embedding complex logic inside core classes
- Using inheritance for every pricing variant
Solution
Step 1: Understand the requirement
Observers can subscribe multiple times to the same event type and should receive multiple notifications accordingly.Step 2: Evaluate data structure changes
Using a set alone disallows duplicates. A list allows duplicates but is not thread-safe and inefficient for removals. A dictionary mapping observers to counts tracks multiple subscriptions safely.Step 3: Choose the best approach
Adding a counter per observer in the set (Keep using a set but add a counter for each observer to track multiple subscriptions.) or using a dictionary (Use a dictionary mapping observers to their subscription counts per event type.) can work, but adding a counter per observer in the set is simpler and keeps thread safety with minimal changes.Final Answer:
Option A -> Option AQuick Check:
Counting subscriptions per observer preserves multiple notifications safely [OK]
- Using list causes concurrency issues and inefficient removals
