Skip to main content

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.