The decorator pattern uses object composition to dynamically change or increase object behavior. The Go language makes it easy to implement decorator patterns with anonymous composition and non-invasive interfaces. With anonymous composition, you do not have to explicitly define callback primitive object methods in decorators.

Design patterns

Decorator mode

Decorator pattern mainly to solve the problem in the inheritance relationship is too complicated, by combining instead of inheritance, add enhancements to the original class, this is also an important basis of judging a decorator besides, decorators and a characteristic, can be used to the original class nested multiple decorators, in order to meet this demand, at the time of design, The decorator class needs an abstract class or interface synchronized with the original inheritance.

Java IO extends many subclasses through four base classes, as follows:

The decorator pattern has the following special points compared to a simple combinatorial relationship:

  • The decorator class inherits the same parent class as the original class, and we can nest multiple decorator classes to the original class.
  • Decorator classes are enhancements to functionality, which is an important feature of the decorator pattern application scenario.

Application scenarios

  • Add responsibilities to a single object dynamically and transparently without affecting other objects.
  • Functions that need to be added to an object dynamically can also be revoked dynamically. When the system cannot be extended by inheritance or inheritance is not conducive to system expansion and maintenance.

code

package decorator type Component interface { Calc() int } type ConcreteComponent struct{} func (*ConcreteComponent) Calc() int { return 0 } type MulDecorator struct { Component num int } func WarpMulDecorator(c Component, num int) Component { return &MulDecorator{ Component: c, num: num, } } func (d *MulDecorator) Calc() int { return d.Component.Calc() * d.num } type AddDecorator struct { Component num int  } func WarpAddDecorator(c Component, num int) Component { return &AddDecorator{ Component: c, num: num, } } func (d *AddDecorator) Calc() int { return d.Component.Calc() + d.num }Copy the code

The test case

package decorator

import (
	"fmt"
	"testing"
)

func TestExampleDecorator(t *testing.T) {
	var c Component = &ConcreteComponent{}
	c = WarpAddDecorator(c, 10)
	c = WarpMulDecorator(c, 8)
	res := c.Calc()

	fmt.Printf("res %d\n", res)
	// Output:
	// res 80
}
Copy the code

The results

=== RUN TestExampleDecorator res 80 -- PASS: TestExampleDecorator (0.00s) PASSCopy the code

Welcome to: Programmer developer community

The resources

  • Github.com/senghoo/gol…
  • Tech.meituan.com/2020/03/19/…
  • Juejin. Cn/post / 684490…