Explain the Factory and Abstract Factory patterns. How do they decouple creation from use, and when do you reach for each?
Spotting when object creation logic should be centralised behind a function so callers depend on an interface, not concrete constructors.
A Factory is a function/method whose job is to CREATE and return objects, hiding the decision of which concrete type to instantiate. The signal to reach for it: callers keep branching on a type to `new` different classes (`if type==='email' new EmailNotifier else new SmsNotifier`), or construction is complex enough that scattering `new` everywhere is fragile. Centralising that in `createNotifier(type)` means callers depend only on the returned interface (`.send()`), so adding a new type touches one place and the rest of the code is untouched — that's the Open/Closed benefit. In JS a factory is often just a function returning an object literal (no class needed), which also sidesteps `new`/`this` pitfalls. Abstract Factory goes one level up: it's a factory that produces FAMILIES of related objects that must be used together, chosen by a single switch. Example: a UI theme factory returns a whole matching set — `{ createButton, createInput, createModal }` — for 'dark' vs 'light', guaranteeing you never mix a dark button with a light modal. So: Factory = 'give me the right ONE object for this input'; Abstract Factory = 'give me a coherent SET of objects for this variant'. Both trade a little indirection for decoupling and a single point of change; skip them when there's only one concrete type and no real variation — that's premature abstraction.
Creation branches on a type or config, construction is non-trivial, or you must produce a matching family of objects for a chosen variant (theme, platform, environment).
O(1) per object created.