liveBook · Manning

Singleton pattern

As explained in Software Design for Python Programmers

The Singleton Design Pattern is a creational design pattern that restricts a class to at most one object instance and provides access to that instance.

The Singleton pattern models a class whose application-wide collection contains at most one object. It controls creation and supplies a shared access point when the object is needed. section 14.0 section 14.1

Why a global variable is not enough

A global ExecutivePass appears to provide one pass, but callers can copy it or explicitly construct another ExecutivePass. The result is duplicated keys, conflicting holders, and an additional global pass. Global state also permits unexpected changes and can create ordering problems during application startup. section 14.1.2

A controlled Singleton implementation:

  • Stores the only object in a private class variable such as _instance, initially None. section 14.1.3
  • Exposes a class method such as obtain() as the access point, creating the object lazily when needed. section 14.1.3
  • Rejects explicit construction by overriding __new__(), and rejects shallow and deep copies through __copy__() and __deepcopy__(). section 14.1.3
  • Provides delete() to clear the stored instance so a later call can create a new one. section 14.1.3

ExecutivePass after refactoring

ExecutivePass.obtain("Ron") and ExecutivePass.obtain("Sal") return the same pass. After ExecutivePass.delete(), obtain("Pat") creates a new pass. Assigning Pat's reference to Leo still leaves one object; calling ExecutivePass() directly raises an exception. section 14.1.3 section 14.1.4

Figure 14.2 A well-designed singleton object. The private class variable _instance is a reference to the singleton object if it exists, or None otherwise. The public class method obtain() returns a reference to the singleton object. It first creates the singleton if it doesn’t already exist.
A computer code with text

AI-generated content may be incorrect.

Use the object diagram to trace _instance, obtain(), lazy creation, and the singleton's global access point. section 14.1.3

Multithreaded code requires additional care: simultaneous checks of an empty _instance can allow multiple threads to create objects. Race-condition avoidance is deferred to multithreaded design. section 14.1.4

How Software Design for Python Programmers covers it

How deep it goes
Explains lazy creation, access control, copy prevention, deletion, and multithreaded race conditions through Python examples.
Examples
Uses PrintSpooler, ExecutivePass, global state, copying, explicit construction, deletion, and reference assignment.
What you can do after
Build it from scratch by controlling construction, access, copying, and replacement in a Python singleton class.
How it connects
Connects Singleton with creational design patterns, Composite, Decorator, and multithreaded program design.

Also explained in

Compare how 6 books explain Singleton pattern →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Software Design for Python Programmers. The section links point to the parts of the book it draws on.