Singleton Design Pattern
Video Lecture
Overview
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.
Singleton UML Diagram

Source Code
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.
./src/singleton/singleton-concept.ts
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 | // Singleton Concept Sample Code
export class Singleton {
// The Singleton Class
static instance: Singleton
id: number
constructor(id: number) {
this.id = id
if (Singleton.instance) {
return Singleton.instance
}
Singleton.instance = this
}
}
// The Client
// All uses of the singleton point to the same original object
const OBJECT1 = new Singleton(1) // setting its id property to 1
const OBJECT2 = new Singleton(2) // setting its id property to 2
console.log(OBJECT1 === OBJECT2) // = true
console.log(OBJECT1.id) // returns 1
console.log(OBJECT2.id) // returns 1
|
Output
node ./dist/singleton/singleton-concept.js
true
Singleton Use Case
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.
Example UML Diagram

Source Code
./src/singleton/client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | // Singleton Use Case Example Code
import { Game1 } from './game1'
import { Game2 } from './game2'
import { Game3 } from './game3'
// The Client
// Despite all games instantiating a leaderboard, they all point
// to the same memory object since the leaderboard is a singleton.
const GAME1 = new Game1()
GAME1.addWinner(2, 'Cosmo')
const GAME2 = new Game2()
GAME2.addWinner(3, 'Sean')
const GAME3 = new Game3()
GAME3.addWinner(1, 'Emmy')
GAME1.leaderboard.print()
GAME2.leaderboard.print()
GAME3.leaderboard.print()
|
./src/singleton/game1.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | // A Game Class that uses the Leaderboard Singleton
import Leaderboard from './leaderboard'
import Game from './igame'
export class Game1 implements Game {
leaderboard: Leaderboard
constructor() {
this.leaderboard = new Leaderboard()
}
addWinner(position: number, name: string): void {
this.leaderboard.addWinner(position, name)
}
}
|
./src/singleton/game2.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | // A Game Class that uses the Leaderboard Singleton
import Leaderboard from './leaderboard'
import Game from './igame'
export class Game2 implements Game {
leaderboard: Leaderboard
constructor() {
this.leaderboard = new Leaderboard()
}
addWinner(position: number, name: string): void {
this.leaderboard.addWinner(position, name)
}
}
|
./src/singleton/game3.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | // A Game Class that uses the Leaderboard Singleton
import Leaderboard from './leaderboard'
import Game from './igame'
export class Game3 implements Game {
leaderboard: Leaderboard
constructor() {
this.leaderboard = new Leaderboard()
}
addWinner(position: number, name: string): void {
this.leaderboard.addWinner(position, name)
}
}
|
./src/singleton/leaderboard.ts
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 | // A Leaderboard Singleton Class
export default class Leaderboard {
static instance: Leaderboard
#table: { [id: number]: string } = {}
constructor() {
if (Leaderboard.instance) {
return Leaderboard.instance
}
Leaderboard.instance = this
}
public addWinner(position: number, name: string): void {
this.#table[position] = name
}
public print(): void {
console.log('-----------Leaderboard-----------')
for (const key in this.#table) {
console.log(`|\t${key}\t|\t${this.#table[key]}\t|`)
}
console.log()
}
}
|
./src/singleton/igame.ts
| // A Game Interface
export default interface IGame {
addWinner(position: number, name: string): void
}
|
Output
node ./dist/singleton/client
-----------Leaderboard-----------
| 1 | Emmy |
| 2 | Cosmo |
| 3 | Sean |
-----------Leaderboard-----------
| 1 | Emmy |
| 2 | Cosmo |
| 3 | Sean |
-----------Leaderboard-----------
| 1 | Emmy |
| 2 | Cosmo |
| 3 | Sean |
Summary
... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.