Practice
print(coffee.description()) and print(coffee.cost()) after wrapping a SimpleCoffee with MilkDecorator (amount=2) and then SugarDecorator (amount=1)?Solution
Step 1: Trace description calls
Starting from SugarDecorator: description() calls MilkDecorator.description(), which calls SimpleCoffee.description() returning "Coffee". Then MilkDecorator adds ", Milk(2)", SugarDecorator adds ", Sugar(1)" -> "Coffee, Milk(2), Sugar(1)".Step 2: Trace cost calls
SimpleCoffee.cost() = 5. MilkDecorator adds 0.5 * 2 = 1. SugarDecorator adds 0.3 * 1 = 0.3. Total cost = 5 + 1 + 0.3 = 6.3.Final Answer:
Option A -> Option AQuick Check:
Description order matches wrapping order; cost sums correctly [OK]
- Mixing order of decorators in description
- Forgetting to multiply cost by amount
Solution
Step 1: Understand the requirement for families of related objects
The problem states the need to create related vehicles (e.g., electric car and electric bike) that belong to a family and must be consistent.Step 2: Match pattern to requirement
Abstract Factory is designed to create families of related objects, ensuring that the created objects are compatible and consistent.Final Answer:
Option B -> Option BQuick Check:
Abstract Factory creates related object families, Factory creates single objects [OK]
- Confusing Factory with Abstract Factory
- Using Builder for simple object creation
print(house) after constructing a basic house with the Director?Solution
Step 1: Trace Director.construct_basic_house()
The Director calls build_walls() and build_roof() on the builder, adding "Walls" and "Roof" to the house parts.Step 2: Check the final house parts list
The house parts list contains ["Walls", "Roof"]. The pool is not added in this method.Final Answer:
Option A -> Option AQuick Check:
Only walls and roof are added in basic house construction [OK]
- Assuming pool is added by default
- Mixing order of parts
import copy
class Profile:
def __init__(self, name, scores):
self.name = name
self.scores = scores
def __deepcopy__(self, memo):
new_name = copy.deepcopy(self.name, memo)
new_scores = copy.deepcopy(self.scores, memo)
return Profile(new_name, new_scores)
original = Profile('Alice', [10, 20])
copy_obj = copy.deepcopy(original)
print('Original scores:', original.scores)
print('Copy scores:', copy_obj.scores)
copy_obj.scores.append(30)
print('After modifying copy scores:')
print('Original scores:', original.scores)
print('Copy scores:', copy_obj.scores)
Solution
Step 1: Trace initial print statements
Both original.scores and copy_obj.scores start as [10, 20], so first two prints show identical lists.Step 2: Trace modification and final prints
copy_obj.scores.append(30) modifies only the copy's scores list because deep copy created a new list. Original remains [10, 20]. Final prints reflect this separation.Final Answer:
Option B -> Option BQuick Check:
Deep copy prevents shared nested list -> original unchanged [OK]
- Assuming append affects original due to shared reference
Solution
Step 1: Identify responsibilities
The class handles both validation and persistence, two distinct reasons to change.Step 2: Trace change impact
Changing validation rules requires modifying validation code inside the class.Step 3: Side effects
Because persistence logic shares the class, changes risk affecting persistence unintentionally, increasing maintenance risk.Step 4: SRP violation
This coupling violates SRP, as one reason to change (validation) affects unrelated functionality (persistence).Final Answer:
Option B -> Option BQuick Check:
One reason to change should not force changes in unrelated code -> SRP violation.
- Assuming changes affect only related methods without side effects.
- Believing tight coupling is harmless if code is in one class.
- Thinking validation and persistence are always linked.
