Fundamentals 4 min read

How to Dynamically Add Features in Go Using the Decorator Pattern

The article explains the Decorator pattern in Go, defining it as a way to add behavior to objects without altering their structure, illustrates the concept with everyday analogies and provides complete Go code examples—including a basic Showable interface, a plain Girl struct, and makeup decorators that wrap the original object—to demonstrate how layered decorations work transparently at runtime.

Nullbody Notes
Nullbody Notes
Nullbody Notes
How to Dynamically Add Features in Go Using the Decorator Pattern

Decorator Pattern (Decorator)

Definition

It is a pattern that dynamically adds extra functionality to an object without changing its existing structure.

Understanding

For example, a date‑formatting function provides a generic method. When a new date format is needed, additional behavior can be added without modifying the original function, similar to decorating the function.

Another analogy: a woman who does not go out without makeup can become a “goddess” after careful decoration.

Or a bare‑bones house: the structural framework cannot be changed, but interior decoration can transform it into a luxurious home.

These examples show that the original object (woman, house, system function) remains unchanged; extra decorations enrich it, aligning with the Open/Closed Principle.

Code

First, define a generic interface:

type Showable interface {
    Show()
}

Implement a plain "girl" without makeup:

//普通的女生
type Girl struct {}

func (t *Girl) Show() {
    fmt.Print("素颜女生")
}

MakeUpDecorator adds a base layer of decoration:

//MakeUpDecorator 化妆
type MakeUpDecorator struct {
    Showable
}

func (t *MakeUpDecorator) Show() {
    fmt.Print("打粉底(")
    t.Showable.Show()
    fmt.Print(")")
}

LispDecorator adds lipstick on top of the previous decoration:

//LispDecorator 口红
type LispDecorator struct {
    Showable
}

func (t *LispDecorator) Show() {
    fmt.Print("涂口红(")
    t.Showable.Show()
    fmt.Print(")")
}

Putting it together:

func main() {
    //素颜女生
    girl := Girl{}
    girl.Show()
    fmt.Println("")
    //化妆后的女神
    l := LispDecorator{Showable: &MakeUpDecorator{Showable: &Girl{}}}
    l.Show()
    fmt.Println("")
    return
}

Output:

素颜女生
涂口红(打粉底(素颜女生))

The output demonstrates that the plain girl can go out without makeup, or she can be wrapped with multiple decorators to add behavior while the external call remains unchanged and transparent.

Source code address:

https://github.com/gofish2020/gopattern/tree/main/structure/decorator

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 PatternsProgrammingGoDecorator PatternObject Composition
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.