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:
clonepackage 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)
}