Skip to content

Singleton Design Pattern

Video Lecture

Section Video Links
Singleton Pattern Singleton Singleton Pattern  
Singleton Use Case Singleton Use Case Singleton Use Case  

Overview

... To read hidden text, either pause Video Lectures, refer to Book or subscribe to Medium Membership.

Singleton UML Diagram

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

Singleton Use Case 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

1
2
3
4
5
// 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.