THN Interview Prep

Abstract Factory (Creational)

Intent / problem it solves

Provide an interface for creating families of related objects (UI widgets, data access components) without specifying concrete classes. Keeps products from mismatched families (e.g. Mac button with Windows dialog).

When to use / when NOT

Use when you have multiple dimensions of variation (platform, theme, cloud vendor) and products must stay consistent within a family.

Avoid when you only need one product type (prefer Factory Method or a simple factory function).

Structure

Abstract factory declares creation methods for each product kind; concrete factories implement all products for one family.

Loading diagram…

Go example

package main

import "fmt"

type Button interface{ Render() string }
type Checkbox interface{ Toggle() string }

type WinButton struct{}
func (WinButton) Render() string { return "win-button" }

type WinCheckbox struct{}
func (WinCheckbox) Toggle() string { return "win-check" }

type UIFactory interface {
	MakeButton() Button
	MakeCheckbox() Checkbox
}

type WindowsKit struct{}
func (WindowsKit) MakeButton() Button     { return WinButton{} }
func (WindowsKit) MakeCheckbox() Checkbox { return WinCheckbox{} }

func DrawScreen(factory UIFactory) {
	fmt.Println(factory.MakeButton().Render(), factory.MakeCheckbox().Toggle())
}

func main() { DrawScreen(WindowsKit{}) }

JavaScript example

class AuthFactory {
  createTokenService() {
    throw new Error('override');
  }
  createUserStore() {
    throw new Error('override');
  }
}

class OidcFactory extends AuthFactory {
  createTokenService() {
    return { kind: 'oidc', issue: () => 'jwt' };
  }
  createUserStore() {
    return { kind: 'sql', load: (id) => ({ id }) };
  }
}

class SamlFactory extends AuthFactory {
  createTokenService() {
    return { kind: 'saml', issue: () => 'assertion' };
  }
  createUserStore() {
    return { kind: 'ldap', load: (id) => ({ id }) };
  }
}

function bootstrapAuth(factory) {
  const tokens = factory.createTokenService();
  const users = factory.createUserStore();
  return { tokens, users };
}

console.log(bootstrapAuth(new OidcFactory()).tokens.kind);

Interview phrase

“Abstract factory groups related constructors so a ‘theme’ or ‘platform’ stays internally consistent; it trades some complexity for compile-time or review-time guarantees that you do not mix incompatible implementations.”

Use when an LLD module picks stacks of collaborators (storage + queue + metrics) from one vendor or environment—document the factory in LLD case studies next to that module.

Last updated on

Spotted something unclear or wrong on this page?

On this page