learnings

Prototype

Prototype pattern - is a creational design pattern that creates new objects by cloning an existing, pre-configured object instead of instantiating new ones from scratch. This pattern helps to avoid subclasses of an object creator in the client application, like the factory method pattern does, and to avoid the inherent cost of creating a new object in the standard way when it is prohibitively expensive for a given application

This pattern is used when:

This pattern operates with three entities:

  1. AbstractPrototype - declares an interface with a method for cloning, often named clone
  2. ConcretePrototype - implements a cloning method that creates a copy of itself
  3. PrototypeClient - creates a new object by asking the prototype to clone itself

Implementations

Golang

package main

import (
	"fmt"
	"time"
)

// AbstractPCPrototype describes abstract PC prototype.
type AbstractPCPrototype interface {
	Clone() AbstractPCPrototype

	PowerOn() error
	// ...other methods that type should implement to
	// satisfy this interface...
}

type CPU struct {
	CoreCount        uint8
	PowerConsumption int
	Socket           string
}

// NewCPU is a constructor for CPU.
func NewCPU() *CPU {
	// ...perform very expensive operations...
	time.Sleep(5 * time.Second)
	return &CPU{
		CoreCount:        4,
		PowerConsumption: 120,
		Socket:           "AM4",
	}
}

type GPU struct {
	PowerConsumption int
}

// NewGPU is a constructor for GPU.
func NewGPU() *GPU {
	// ...perform very expensive operations...
	time.Sleep(5 * time.Second)
	return &GPU{
		PowerConsumption: 180,
	}
}

type PC struct {
	CPU *CPU
	GPU *GPU
}

// NewPC() is a constructor for new PC.
func NewPC() *PC {
	return &PC{
		CPU: NewCPU(),
		GPU: NewGPU(),
	}
}

func (c *PC) PowerOn() error {
	return nil
}

func (c *PC) Clone() AbstractPCPrototype {
	clone := *c
	return &clone
}

func user(numPCs int, basePC AbstractPCPrototype) {
	batchOfPCs := make([]AbstractPCPrototype, numPCs)
	for i := range numPCs {
		clonePC := basePC.Clone()
		err := clonePC.PowerOn()
		if err != nil {
			panic(err)
		}
		batchOfPCs[i] = clonePC
	}

	// ...process batch...
	fmt.Println(batchOfPCs)
}

func main() {
	// it tooks a good amount of time
	pc := NewPC()
	user(4, pc)
}