Design pattern learning - Implementing prototype patterns using go

Prototype mode


If the cost of creating objects is relatively large, and there is little difference between different objects of the same class (most fields are the same), in this case, we can create new objects by copying (or copying) existing objects (prototypes), so as to save creation time. This method of creating objects based on prototypes is called Prototype Design Pattern, which is called prototype pattern for short.

Prototype mode can be based on copy. We know that there are two forms of copy, deep copy and shallow copy

Shallow copy only copies the pointer to an object, not the object itself. The old and new objects still share the same block of memory. But deep copy as like as two peas will create another object that is exactly the same. New objects do not share memory with original objects, and new objects will not be changed to original objects.

Prototype mode shallow copy:

1. Save memory and faster copy time;

2. Shallow copy is easy to modify the original data, which is generally not recommended;

3. Shallow copy can copy immutable objects;

Prototype mode deep copy:

1. Complete data isolation;

2. However, when there is a large amount of data, deep copy is more time-consuming and memory space consuming than shallow copy;

code implementation

// Clonable is the interface that the prototype object needs to implement
type Cloneable interface {
	Clone() Cloneable

type PrototypeManager struct {
	prototypes map[string]Cloneable

func NewPrototypeManager() *PrototypeManager {
	return &PrototypeManager{
		prototypes: make(map[string]Cloneable),

func (p *PrototypeManager) Get(name string) Cloneable {
	return p.prototypes[name].Clone()

func (p *PrototypeManager) Set(name string, prototype Cloneable) {
	p.prototypes[name] = prototype

Test file

var (
	deepCopyManager    *PrototypeManager
	shallowCopyManager *PrototypeManager

// Deep copy implementation clonable
type DeepCopy struct {
	name string

func (t *DeepCopy) Clone() Cloneable {
	tc := *t
	return &tc

// Shallow copy implementation clonable
type ShallowCopy struct {
	name string

func (t *ShallowCopy) Clone() Cloneable {
	return t

func TestDeepCopyClone(t *testing.T) {
	t1 := deepCopyManager.Get("dc")

	t2 := t1.Clone()
	// Deep copy refers to an address that is not the same variable
	if t1 == t2 {
		t.Fatal("error! get clone not working")

	t21 := t2.(*DeepCopy) = "ShallowCopy-test"

	t11 := t1.(*DeepCopy)
	// Deep copy name will not affect the variables before copy
	if == {
		t.Fatal("shallowCopy err")

func TestShallowCopyClone(t *testing.T) {
	t1 := shallowCopyManager.Get("sc")

	t2 := t1.Clone()
	// For shallow copy, the direction of variable address remains unchanged
	if t1 != t2 {
		t.Fatal("error! get clone not working")

	t21 := t2.(*ShallowCopy) = "ShallowCopy-test"

	t11 := t1.(*ShallowCopy)
	// Deep copy name, variables before copy and variables after copy are changed at the same time
	if != {
		t.Fatal("shallowCopy err")

func init() {
	deepCopyManager = NewPrototypeManager()

	dc := &DeepCopy{
		name: "deepCopy",
	deepCopyManager.Set("dc", dc)

	shallowCopyManager = NewPrototypeManager()
	sc := &ShallowCopy{
		name: "shallowCopy",
	shallowCopyManager.Set("sc", sc)


1. Using prototype mode to create an object is much better than directly new an object, because it is a direct memory copy, which is much better than initialization;

2. Simplify the creation of objects. Creating objects is as simple as copying and pasting when editing documents.


Cloning complex objects with circular references can be cumbersome.

Applicable scenario

1. In the project, if there are a large number of identical or similar objects, it will be more complex and resource consuming to create objects with traditional constructors. It is very efficient to produce objects with prototype mode;

2. Object creation is troublesome, but copying is simple;

reference resources

[code in text] Prototype mode
[big talk design mode]
[geek time]
[prototype mode]
[original address] Using go to implement prototype pattern/

Tags: Design Pattern

Posted on Mon, 08 Nov 2021 06:17:00 -0500 by benn600