Fundamentals 8 min read

Understanding the Prototype Pattern in Go: Clone Objects Efficiently

This article explains the Prototype design pattern in Go, shows how to clone objects with various implementations, compares their effects on object independence, and clarifies Go's value‑semantic parameter passing using concrete code examples and detailed analysis.

Nullbody Notes
Nullbody Notes
Nullbody Notes
Understanding the Prototype Pattern in Go: Clone Objects Efficiently

Prototype Pattern Definition

Use an already created instance as a prototype and create a new object that is the same or similar by copying the prototype.

Example: a Chips struct with fields Name, Color, Kind, and Calorie. Creating a 薯条 (fries) object and then a 薯片 (chips) object requires repeating almost identical struct literals, which motivates copying the existing object and modifying only the differing fields.

Go Implementation

package prototype

type File struct {
    Context string
}

func (t *File) Clone() *File { // returns a copy, independent
    fake := *t
    return &fake
}

func (t *File) Clone1() *File { // constructs a new File, independent
    return &File{Context: t.Context}
}

func (t *File) Clone2() *File { // returns the original pointer, shared
    return t
}

func (t *File) Clone3() File { // returns a value copy, independent
    return *t
}

func (t File) Clone4() *File { // receives a copy, returns its address, independent
    return &t
}

func (t File) Clone5() File { // returns the copy directly, independent
    return t
}

func NewFile() *File {
    return &File{Context: "new file"}
}

The main function creates a file via NewFile(), clones it with Clone() (or any of the other Clone variants), prints the contexts, modifies the clone's context, and prints again to show that the original and clone are separate variables.

func main() {
    fmt.Println("Prototype Pattern")
    file := prototype.NewFile()
    clone := file.Clone() // replace with Clone1‑Clone5 to observe different behaviours
    fmt.Printf("file.Context: %v 
clone.Context: %v 
", file.Context, clone.Context)
    clone.Context = "cloned file"
    fmt.Printf("file.Context: %v 
clone.Context: %v 
", file.Context, clone.Context)
}
Output shows that after changing clone.Context , the two contexts differ, confirming that file and clone are distinct variables.

Analysis of Clone Variants

Clone : creates a local variable fake := *t (a copy of the original struct) and returns its address. The pointer refers to a different memory location, so modifications to the clone do not affect the original.

Clone1 : constructs a new File with the same Context and returns its address. This also yields an independent object.

Clone2 : returns the original pointer t. Both variables point to the same memory, so changes to one affect the other.

Clone3 : returns the dereferenced struct value *t. The caller receives a copy, which is independent of the original.

Clone4 : receives the struct by value (a copy) and returns the address of that copy. The pointer refers to a distinct copy, so it is independent.

Clone5 : returns the value copy directly, again independent of the original.

These examples illustrate that Go always passes arguments by value. When a pointer is passed, the pointer value itself is copied; both copies still refer to the same underlying data, which explains the shared‑state behaviour of Clone2.

C Analogy

int *tree(int *p) {
    int *m = p; // m gets the same address as p
    p = null;   // change local p, does not affect caller's pointer
    return m;  // return m, which still points to the original int
}

void main() {
    int a = 3;
    int *b = &a;
    int *c = tree(b);
}
After the call, p is null, b still points to a , and c also points to a , demonstrating value copying of pointers.

Conclusion

The Prototype pattern in Go is straightforward: a method named Clone typically implements this pattern. Understanding the different ways to return a clone clarifies Go's value‑semantic parameter passing and helps avoid unintended shared state.

Source code repository: https://github.com/gofish2020/gopattern/tree/main/creator

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsClonePrototype PatternValue Semantics
Nullbody Notes
Written by

Nullbody Notes

Go backend development, learning open-source project source code together, focusing on simplicity and practicality.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.