# Golang - Decorator Pattern

The Decorator Pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other objects from the same class.

The "Gang of Four" patterns book describes the Decorator Pattern as "attaching additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality."

# Example

In Golang, the Decorator Pattern can be implemented using interfaces and anonymous functions. Let's see a code example:

```go
package main

import "fmt"

type Printer interface {
    Print() string
}

type SimplePrinter struct {}

func (sp *SimplePrinter) Print() string {
    return "Hello, world!"
}

func BoldDecorator(p Printer) Printer {
    return PrinterFunc(func() string {
        return "<b>" + p.Print() + "</b>"
    })
}

type PrinterFunc func() string

func (pf PrinterFunc) Print() string {
    return pf()
}

func main() {
    simplePrinter := &SimplePrinter{}
    boldPrinter := BoldDecorator(simplePrinter)

    fmt.Println(simplePrinter.Print()) // Output: Hello, world!
    fmt.Println(boldPrinter.Print()) // Output: <b>Hello, world!</b>
}
```

In the code example above, we declare a `Printer` interface and a `SimplePrinter` struct that implements the `Print()` method.

Then we define the `BoldDecorator` function that receives a `Printer` interface and returns another `Printer` interface. This function wraps the original `Print()` method in a new one that returns the same value enclosed in `<b>` tags.

This is a simple example, but it shows the power of the Decorator Pattern. By adding a new decorator, we can change the behavior of an object at runtime without changing its original code.

The Decorator Pattern is especially useful when we have to add new functionality to an object that already exists and we want to keep its original code untouched. In this way, we can avoid creating new subclasses for every new feature we want to add.

# Middleware Decorator

Another example where we can use the Decorator Pattern is in the implementation of middleware in web frameworks. Middleware functions are functions that execute before or after a request is handled by a web server. They can be used for tasks such as authentication, logging, and caching.

In Golang, we can use the Decorator Pattern to implement middleware functions. We can define a `Handler` interface that represents a function that handles an HTTP request and returns an HTTP status code and a response body. Then we can define a `Middleware` interface that receives a `Handler` and returns another `Handler` that executes some additional behavior before or after the original `Handler` is called.

Here's an example:

```go
package main

import (
    "fmt"
    "net/http"
)

type Handler func(r *http.Request) (int, string)

type Middleware func(h Handler) Handler

func LoggingMiddleware(h Handler) Handler {
    return func(r *http.Request) (int, string) {
        fmt.Println("Handling request...")
        status, body := h(r)
        fmt.Printf("Request handled with status %d\\\\n", status)
        return status, body
    }
}

func main() {
    helloHandler := func(r *http.Request) (int, string) {
        return http.StatusOK, "Hello, world!"
    }

    loggingHandler := LoggingMiddleware(helloHandler)

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        status, body := loggingHandler(r)
        w.WriteHeader(status)
        w.Write([]byte(body))
    })

    http.ListenAndServe(":8080", nil)
}
```

In this example, we define a `Handler` function that returns an HTTP status code and a response body. Then we define a `LoggingMiddleware` function that receives a `Handler` and returns another `Handler` that logs the incoming request and the outgoing response.

Finally, in the `main()` function, we create a new `http.HandleFunc` that receives a logging `Handler` and returns an HTTP response with the same status code and body returned by the `Handler`.

# Conclusion

In conclusion, the Decorator Pattern is a powerful design pattern that can be used in many contexts to create more flexible and extensible code. In Golang, this pattern can be implemented using interfaces and anonymous functions, and it can be used to add new functionality to an existing codebase without affecting its original code.

I hope you found this article useful! If you have any questions or suggestions, please leave a comment below.

---

# References

* [**“Design Patterns: Elements of Reusable Object-Oriented Software**](https://amzn.to/3SJenIZ)” by Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm
