Module Quiz
Complete this quiz after finishing all concept and practice pages.
Current Module Questions
Question 1: Strategy's Axis of Variation
Why is "Strategy for the one discount formula we have" an anti-pattern, and what would you do instead?
Answer: There is no variation to absorb. An interface plus one implementation adds ceremony and test surface without relieving any pressure. Inline the code; introduce the Strategy when a second algorithm actually appears.
Question 2: Strategy vs Function Reference
Give two properties that push you from a function reference toward a Strategy object.
Answer: Multiple related methods on the strategy, or construction-time configuration and lifecycle (resources, close()). A single stateless method is usually better as a function.
Question 3: Template Method vs Strategy
In one sentence, what is the practical difference between Template Method and Strategy?
Answer: Template Method uses inheritance to vary steps inside a fixed skeleton at compile time; Strategy uses composition to swap an algorithm at runtime.
Question 4: Observer Coupling Direction
In an Observer pattern, which of the subject and observer depends on the other, and why does that matter?
Answer: The subject depends only on the observer interface. Concrete observer classes can be added without modifying the subject, which is the Open/Closed benefit the pattern provides.
Question 5: Observer Pitfall
You iterate this.listeners directly during publish. One listener calls unsubscribe(self) inside its update. What happens and how do you prevent it?
Answer: The list mutates while iterating, producing skipped listeners or exceptions. Snapshot the list (copy before iterating), or queue subscription changes and apply them after the notification finishes.
Question 6: Push vs Pull
A subject has a large state object but different observers need different slices of it. Which notification style is better, and why?
Answer: Pull. Passing the whole state to every observer wastes bandwidth and couples them to a fat shape; passing the subject lets each observer read only what it needs.
Question 7: Command vs Function
Name one capability that Command gives you that a bare function reference does not.
Answer: Any of: undo by undo(), a stable serializable representation, attached metadata (label, timestamp, ID), or inspection by the invoker or a logger before execution.
Question 8: Undo by Inverse vs Snapshot
When is "snapshot then restore" preferable to implementing an explicit inverse operation?
Answer: When the inverse is hard, lossy, or ambiguous -- e.g., a Clear or a large bulk replacement -- and when the state to back up is small enough to store cheaply.
Question 9: Command Queue Idempotency
A queue with at-least-once delivery runs your SendEmail command. What is the risk, and how do you fix it?
Answer: The same command may run twice. Require a command ID and make the handler idempotent by recording processed IDs so re-delivery is a no-op.
Question 10: State vs Strategy
Give the one sentence that distinguishes State from Strategy.
Answer: In State, the helper objects know about each other and drive transitions; in Strategy, the helpers are independent and the client chooses which one is active.
Question 11: State Refactor Smell
Which Fowler smell most directly motivates refactoring to State, and why?
Answer: Repeated Switches. The same switch over a status field appears in multiple methods, so every new state or operation forces parallel edits.
Question 12: FSM Representations
You have a lifecycle with 4 states and 6 events, rich behavior per state. Which representation do you pick and why?
Answer: State pattern (polymorphic states), because rich per-state behavior benefits from a class boundary; a transition table is better when the table is the dominant feature and behavior is simple.
Question 13: Iterator Responsibility
Whose responsibility is it to hold the current position during traversal: the collection or the iterator?
Answer: The iterator. This is what allows multiple independent walks of the same collection without them interfering, and it is why the collection should not expose its internal index.
Question 14: Chain of Responsibility Default
What is the safest default forwarding policy for a base handler class in CoR, and why?
Answer: Forward by default; require concrete handlers to opt out explicitly. A silent swallow is a common bug, and making forwarding the default reduces the chance of lost requests.
Question 15: Visitor Trade-Off
What grows cheaply and what grows expensively when you adopt Visitor?
Answer: Operations grow cheaply (add a new visitor class; elements are untouched). Element types grow expensively (every visitor must add a new visit method). Choose Visitor when operations churn more than element types.
Interleaved Review Questions
Prior Module Question 1 (from S3M1)
Name one cohesion problem that makes a class a candidate for Strategy extraction.
Answer: A class mixing an unchanged skeleton with one step that has many variants -- the varying step violates single-responsibility and is the natural extraction candidate.
Prior Module Question 2 (from S3M1)
What does "coupling to a concrete class" look like in practice, and why does Observer specifically break it?
Answer: Importing and instantiating a concrete class directly. Observer breaks it by making the subject depend only on an observer interface, so concrete observers can change independently.
Prior Module Question 3 (from S3M2)
Before refactoring a switch-heavy class to State, what must you put in place?
Answer: Characterization tests covering current valid and invalid transitions, so each small refactor step can be verified to preserve behavior.
Prior Module Question 4 (from S3M2)
Which refactor move, from the Fowler catalog, is the core engine of the State pattern refactor?
Answer: Replace Conditional with Polymorphism.
Prior Module Question 5 (from S3M2)
Why would you prefer an incremental refactor to State over rewriting the class in one shot?
Answer: Because each small step is provable by tests; a one-shot rewrite is a merge- and regression-hazard, and the pattern's benefits do not depend on doing it all at once.
Self-Assessment and Remediation
Mastery Level (90-100% correct):
- Ready to advance. Reinforce by teaching one pattern from memory before moving to Module 4.
Proficient Level (75-89% correct):
- Review only the concept pages for the missed questions. Redo the corresponding kata once.
Developing Level (60-74% correct):
- Rework the practice page most closely related to the missed cluster (Lab, Workshop, or Clinic).
- Redo two katas in the affected cluster and add your mistakes to the log.
Insufficient Level (<60% correct):
- Return to the concept pages in the missed cluster and the listed "Read This Only If Stuck" chunks. Rebuild the pattern-selection habits (pressure -> pattern) before advancing.