0 XP · 0 scenes

Singleton

Exactly one instance, reachable from anywhere
The problem

Every module builds its own Config.

The idea

Hide the constructor and keep the one instance inside the class.

Reach for it when

Exactly one object must coordinate things (config, registry, connection pool)

1

The picture from life

A school has one principal. Whoever wants the principal asks the office and is shown the same person; nobody hires a second principal just because they have a question. The school makes sure there is only ever one.

2

The problem

What goes wrong when you do not use it.

Every module builds its own Config. One reads the file, another reads it again, a third changes a value that the others never see. You now have three "truths" and wasted loads.

✗ Before
Module AModule Bconfig #1theme = darkconfig #2theme = lightConfig()Config()
  • creates
Every module creates its own Config. Two copies, two file reads, and they can disagree.
Reach for it when
  • Exactly one object must coordinate things (config, registry, connection pool)
  • Everyone must see the same state
  • Creating it is expensive and should happen once
3

The idea

How the pattern fixes it.

Hide the constructor and keep the one instance inside the class. A static get() creates it the first time and hands back the same object afterwards.

✓ After
Module AModule BConfig- _instance+ get()Config.get()Config.get()
  • calls / uses
One shared instance. Everyone asks Config.get() and receives the same object.

Who is who

Config
The class that must have one instance. Constructor is private (or by convention not called).
get()
The only door. Creates on first call, returns the saved object afterwards.
Callers
Always use Config.get(); never create one.

Build it in steps

  1. 1Make the constructor private (Java) or never call it directly.
  2. 2Keep a static field for the single instance.
  3. 3Add a static get() that creates it once.
  4. 4Make creation thread-safe if threads are involved.
4

Watch it run

Step through the calls. Tap an arrow to jump to it.

Module AConfigModule B1Config.get()2cls()3instance4Config.get()5same instance
Step 1/5

Module A asks for the config. Nobody has created it yet.

Config.get()
5

The code

Python and Java. Try writing the classes yourself from the diagram first.

class Config:
    _instance = None

    def __init__(self):
        self.values = {"theme": "dark"}

    @classmethod
    def get(cls):
        if cls._instance is None:          # first call creates it
            cls._instance = cls()
        return cls._instance               # every later call returns the same object


def demo():
    first = Config.get()
    second = Config.get()
    first.values["theme"] = "light"
    return first is second, second.values["theme"]

What you gain

  • One shared state, created once
  • Lazy: built only if someone asks

What it costs

  • It is global state in disguise: hard to test and easy to abuse
  • Needs care with threads
  • Prefer passing the one object in (dependency injection) when you can

You have already met it in

  • Runtime in Java (Runtime.getRuntime())
  • Spring beans are singletons by default
  • A logger or a database connection pool

Often mixed up with

  • FlyweightFlyweight shares many small objects; Singleton makes sure only one object of a class exists.
6

Make it stick

Build a Logger singleton whose messages list is shared by two classes. Then rewrite it by passing the logger into both classes and compare how easy each is to test.

Confidence