Singleton Design Pattern
Video Lecture
Overview
... Refer to Book, pause Video Lectures or subscribe to Medium Membership to read textual content.
Singleton UML Diagram

Source Code
... Refer to Book, pause Video Lectures or subscribe to Medium Membership to read textual content.
./singleton/singleton_concept.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | # pylint: disable=too-few-public-methods
"Singleton Concept Sample Code"
import copy
class Singleton():
"The Singleton Class"
value = []
def __new__(cls):
return cls
# def __init__(self):
# print("in init")
@staticmethod
def static_method():
"Use @staticmethod if no inner variables required"
@classmethod
def class_method(cls):
"Use @classmethod to access class level variables"
print(cls.value)
# The Client
# All uses of singleton point to the same memory address (id)
print(f"id(Singleton)\t= {id(Singleton)}")
OBJECT1 = Singleton()
print(f"id(OBJECT1)\t= {id(OBJECT1)}")
OBJECT2 = copy.deepcopy(OBJECT1)
print(f"id(OBJECT2)\t= {id(OBJECT2)}")
OBJECT3 = Singleton()
print(f"id(OBJECT1)\t= {id(OBJECT3)}")
|
Output
| python ./singleton/singleton_concept.py
id(Singleton) = 2164775087968
id(OBJECT1) = 2164775087968
id(OBJECT2) = 2164775087968
id(OBJECT3) = 2164775087968
|
... Refer to Book, pause Video Lectures or subscribe to Medium Membership to read textual content.
Example Use Case
... Refer to Book, pause Video Lectures or subscribe to Medium Membership to read textual content.
Example UML Diagram

Source Code
./singleton/client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | # pylint: disable=too-few-public-methods
"Singleton Use Case Example Code."
from game1 import Game1
from game2 import Game2
from game3 import Game3
# The Client
# All games share and manage the same leaderboard because it is a singleton.
GAME1 = Game1()
GAME1.add_winner(2, "Cosmo")
GAME2 = Game2()
GAME2.add_winner(3, "Sean")
GAME3 = Game3()
GAME3.add_winner(1, "Emmy")
GAME1.leaderboard.print()
GAME2.leaderboard.print()
GAME3.leaderboard.print()
|
./singleton/game1.py
1
2
3
4
5
6
7
8
9
10
11
12
13 | "A Game Class that uses the Leaderboard Singleton"
from leaderboard import Leaderboard
from interface_game import IGame
class Game1(IGame): # pylint: disable=too-few-public-methods
"Game1 implements IGame"
def __init__(self):
self.leaderboard = Leaderboard()
def add_winner(self, position, name):
self.leaderboard.add_winner(position, name)
|
./singleton/game2.py
1
2
3
4
5
6
7
8
9
10
11
12
13 | "A Game Class that uses the Leaderboard Singleton"
from leaderboard import Leaderboard
from interface_game import IGame
class Game2(IGame): # pylint: disable=too-few-public-methods
"Game2 implements IGame"
def __init__(self):
self.leaderboard = Leaderboard()
def add_winner(self, position, name):
self.leaderboard.add_winner(position, name)
|
./singleton/game3.py
| "A Game Class that uses the Leaderboard Singleton"
from game2 import Game2
class Game3(Game2): # pylint: disable=too-few-public-methods
"""Game 3 Inherits from Game 2 instead of implementing IGame"""
|
./singleton/leaderboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | "A Leaderboard Singleton Class"
class Leaderboard():
"The Leaderboard as a Singleton"
_table = {}
def __new__(cls):
return cls
@classmethod
def print(cls):
"A class level method"
print("-----------Leaderboard-----------")
for key, value in sorted(cls._table.items()):
print(f"|\t{key}\t|\t{value}\t|")
print()
@classmethod
def add_winner(cls, position, name):
"A class level method"
cls._table[position] = name
|
./singleton/interface_game.py
| # pylint: disable=too-few-public-methods
"A Game Interface"
from abc import ABCMeta, abstractmethod
class IGame(metaclass=ABCMeta):
"A Game Interface"
@staticmethod
@abstractmethod
def add_winner(position, name):
"Must implement add_winner"
|
Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | python ./singleton/client.py
-----------Leaderboard-----------
| 1 | Emmy |
| 2 | Cosmo |
| 3 | Sean |
-----------Leaderboard-----------
| 1 | Emmy |
| 2 | Cosmo |
| 3 | Sean |
-----------Leaderboard-----------
| 1 | Emmy |
| 2 | Cosmo |
| 3 | Sean |
|
New Coding Concepts
Python Dictionary
In the file ./singleton/leaderboard.py,
| "The Leaderboard as a Singleton"
_table = {}
|
The {}
is indicating a Python Dictionary.
A Dictionary can be instantiated using the curly braces {}
or dict()
The Dictionary is similar to a List, except that the items are key:value
pairs.
The Dictionary can store multiple key:value
pairs, they can be changed, can be added and removed, can be re-ordered, can be pre-filled with key:value
pairs when instantiated and is very flexible.
Since Python 3.7, dictionaries are ordered in the same way that they are created.
The keys of the dictionary are unique.
You can refer to the dictionary items by key, which will return the value.
| PS> python
>>> items = {"abc": 123, "def": 456, "ghi": 789}
>>> items["abc"]
123
|
You can change the value at a key,
| PS> python
>>> items = {"abc": 123, "def": 456, "ghi": 789}
>>> items["def"] = 101112
>>> items["def"]
101112
|
You can add new key:value
pairs, and remove them by using the key.
| PS> python
>>> items = {"abc": 123, "def": 456, "ghi": 789}
>>> items["jkl"] = 101112
>>> items["jkl"]
101112
>>> items.pop('def')
456
>>> items
{'abc': 123, 'ghi': 789, 'jkl': 101112}
|
You can order a dictionary alphabetically by key
| PS> python
>>> items = {"abc": 123, "ghi": 789, "def": 456}
>>> items
{'abc': 123, 'ghi': 789, 'def': 456}
>>> dict(sorted(items.items()))
{'abc': 123, 'def': 456, 'ghi': 789}
|
Summary
... Refer to Book, pause Video Lectures or subscribe to Medium Membership to read textual content.