SerialReads

design-patterns

GoF Creational Patterns Flash Deck

Quick-fire revision cards covering the five classic “Gang of Four” creational patterns— Singleton, Factory Method, Abstract Factory, Builder, and Prototype. The deck is tiered roughly easy → medium → hard to test both recall and deeper insight. Click a card to reveal the answer.

1. Singleton (Easy) – What problem does the Singleton pattern address?

Guarantees exactly one instance of a class per process and provides a global access point to it (common for configs, logging, caches, connection pools).

2. Singleton (Medium) – Compare *eager* vs *lazy* Singleton initialization.

Eager: instance built at class-loading time; inherently thread-safe but may waste resources if never used.
Lazy: instance created on first getInstance(); conserves memory but needs extra thread-safety (double-checked locking, static-holder idiom).

3. Singleton (Hard) – Give two common pitfalls of Singletons and mitigations.
  1. Hidden dependencies → prefer DI / pass interfaces.
  2. Hard-to-test state → allow test-only swapping or use service locators.
  3. Serialization/Reflection attacks → guard with readResolve() and private constructors.
4. Factory Method (Easy) – What does Factory Method add over a direct `new` call?

Encapsulates creation in a creator that returns a product interface; concrete subclasses choose which product to instantiate, enabling extension without changing client code.

5. Factory Method (Medium) – When choose Factory Method over Abstract Factory?

Use it when you need only one product whose variant is determined by subclasses. Pick Abstract Factory if you must create whole families of related products that must remain compatible.

6. Factory Method (Hard) – How does Factory Method uphold the open–closed principle?

Clients depend only on the creator interface; adding new concrete products extends behaviour without modifying existing clients. Trade-off: growth of subclasses and tighter coupling between creator and concrete products.

7. Abstract Factory (Easy) – Give a real-world analogy for Abstract Factory.

A furniture showroom selling “Victorian” or “Modern” sets—choose one factory to get a chair, sofa, and table that match in style.

8. Abstract Factory (Medium) – How does the pattern aid cross-platform UI toolkits?

App selects a concrete factory at start-up (Windows, macOS, Linux); each factory knows how to build native widgets, so application code never touches platform-specific classes.

9. Abstract Factory (Hard) – Contrast Abstract Factory with Builder.

Abstract Factory: creates multiple related products all at once; focuses on product families & compatibility.
Builder: assembles one complex product step-by-step, allowing optional parts and varying construction sequences.

10. Builder (Easy) – What headache does Builder cure for objects with many parameters?

Eliminates “telescoping constructors” by letting clients set only needed fields and chain optionals fluently; build() then returns an immutable object.

11. Builder (Medium) – Why still useful in languages with named/optional params?

Can validate progressively, enforce ordering rules, and hide complex default logic that would clutter a single constructor call.

12. Builder (Hard) – Identify a performance drawback of classic Java Builders.

Builder holds duplicate fields, so large objects may be copied twice. Mitigate with lazy suppliers or use a mutable product plus director for high-volume cases.

13. Prototype (Easy) – Define the Prototype pattern in one sentence.

Creates new objects by cloning an existing prototype instead of instantiating a class directly.

14. Prototype (Medium) – Differentiate *shallow* vs *deep* copy in Prototype.

Shallow: fields copied by reference; clones share sub-objects → fast but risky if internals mutate.
Deep: recursively duplicates referenced objects → safe isolation, higher cost.

15. Prototype (Hard) – How clone an acyclic graph with back-references safely?

Maintain a map<original, clone>; DFS/BFS each node: if not in map, create a stub clone, store it, then recurse on neighbours and wire cloned edges—each original visited once, preventing infinite loops.

← Back to all decks