learnings

Singleton

This pattern restricts instantiation of a class to a single instance and provides global access point to that instance.

This pattern is used when:

The pattern operates with only one entity: Singleton - provides access to the instance over Instance method and ensures that there is only one instance exists.

Implementation examples

Golang

package main

import "errors"

var alreadyInstantiated = false
var instance *ExampleManufacturer = nil

type Manufacturer interface {
	RequestGPU() GPU
	RequestMotherboard() Motherboard
}

type GPU struct{}
type Motherboard struct{}

type ExampleManufacturer struct {
	GPUs         []GPU
	Motherboards []Motherboard
}

func NewExampleManufacturer() (*ExampleManufacturer, error) {
	if alreadyInstantiated {
		return nil, errors.New("already instantiated")
	}
	instance = &ExampleManufacturer{
		GPUs:         make([]GPU, 3),
		Motherboards: make([]Motherboard, 2),
	}
	return instance, nil
}

func (m *ExampleManufacturer) RequestGPU() (*GPU, error) {
	if len(m.GPUs) == 0 {
		return nil, errors.New("no GPUs left")
	}
	gpu := m.GPUs[0]
	m.GPUs = m.GPUs[1:]
	return &gpu, nil
}
func (m *ExampleManufacturer) RequestMotherboard() Motherboard {}
func (m *ExampleManufacturer) Instance() *ExampleManufacturer  {
	if alreadyInstantiated {
		return instance
	}

	
}

Python

Python is more of an OOP language and provides more OOP features than Golang, so the implementation of a singleton in Python is more concise and canonical.

import random

class SingletonError(Exception):...

class ExampleManufacturer:
    __instance = None

    def __new__(cls):
        if cls.__instance is not None:
            raise SingletonError("already instanciated")
        cls.__instance = super().__new__(cls)
        return cls.__instance

    def __init__(self):
        self.GPUs: list[int] = [random.randint(1, 5) for _ in range(5)]
        self.Motherboards: list[int] = [random.randint(1, 5) for _ in range(5)]
    
    @classmethod
    def instance(cls):
        return cls.__instance
            

def main():
    manufacturer = ExampleManufacturer()
    print(manufacturer.GPUs)

    try:
        again = ExampleManufacturer()
    except SingletonError:
        print("cant instantiate another instance of a class")
    
    again = ExampleManufacturer.instance()
    print(again.GPUs)



if __name__ == '__main__':
    main()