notesonly.in

One notebook for every subject — open it anywhere.

Log in

Design Patterns: Singleton, Factory and Observer Guide.

Design patterns are proven, reusable solutions to problems that appear again and again in software design. Catalogued famously by the "Gang of Four" in 1994, the 23 classic patterns fall into three families: creational (how objects are made), structural (how objects are composed) and behavioural (how objects communicate). Three of the most used are Singleton, Factory and Observer.

They matter because they give engineers a shared vocabulary. Saying "use an Observer here" communicates a complete design — roles, interactions and trade-offs — in three words, the way "sonnet" tells a poet the whole structure of the poem. Patterns also distil decades of hard-won experience about what actually works.

Key Concepts

  • Singleton (creational): guarantees a class has exactly one instance and provides global access to it. The constructor is private, and a static method like getInstance() returns the single shared object. Classic uses: configuration managers and loggers.
  • Factory (creational): creates objects without exposing which concrete class is instantiated. Client code asks the factory for a "button" and gets a WindowsButton or MacButton as appropriate, so adding a new platform never touches client code.
  • Observer (behavioural): defines a one-to-many dependency: when the subject changes state, all registered observers are notified automatically. A YouTube channel notifying subscribers of a new video is the everyday example.
  • Pattern vs. code snippet: a pattern is a template you adapt, not code you paste. The idea transfers across languages; the implementation differs.

How It Works

  • Singleton flow: first call to Logger.getInstance() creates the one logger; every later call returns that same object, so all 5,000 requests in a minute share one log file handle instead of fighting over many.
  • Factory flow: the UI toolkit's createDialog("error") returns an ErrorDialog on any OS; when a Linux port is added, only the factory learns the new class and no calling code changes.
  • Observer flow: a stock-price subject keeps a list of 200 subscribed trader apps; on every price tick it loops through the list calling update(price) on each, so all screens refresh within milliseconds of the change.

Worked Example

Compare resource usage with and without the Singleton pattern for a configuration object.

  1. Suppose each request handler builds its own Config object occupying 50 MB, and the server handles 5,000 requests.
  2. Without Singleton: 5,000 × 50 MB = 250,000 MB ≈ 250 GB of memory churned through, repeatedly loading the same settings.
  3. With Singleton: one 50 MB object is created once and shared by all 5,000 handlers — total 50 MB.
  4. Saving: 250 GB − 0.05 GB ≈ 249.95 GB of allocation avoided, plus the CPU time of 4,999 redundant file reads.
  5. The trade-off: every handler now depends on global state, which is exactly why Singleton should be reserved for genuinely single things like configuration, not used as a convenient global variable.

Common Misconceptions

  • "Patterns are code to copy and paste." They are design templates. A textbook Singleton pasted blindly into a multithreaded app can create two instances; the pattern must be adapted to the context.
  • "Singleton is always good design." It hides dependencies and makes unit testing painful, since tests cannot easily substitute a fake. Use it for truly singular resources, not as a shortcut.
  • "More patterns mean better design." Forcing patterns where none fit produces over-engineered code that is harder to read than a straightforward solution. The simplest design that works wins.

Real-World Applications

  • Logging and configuration: Singleton loggers and config managers appear in nearly every server application.
  • UI toolkits: factories create platform-appropriate widgets so one codebase runs on Windows, macOS and Linux.
  • Event systems: GUI frameworks, message brokers and reactive streams are Observer patterns at scale.
  • Payment gateways: factories pick the right processor (UPI, card, wallet) per transaction without the checkout code caring.

Singleton controls how many exist, Factory controls how things are created, and Observer controls how change spreads. Learn these three deeply — when each fits and what each costs — and you will start recognising them everywhere in professional code.