The schema definition

Adding some additional responsibility to an object dynamically (in combination), the Decorator pattern is more flexible in terms of adding functionality than generating subclasses (inheritance) (eliminating duplicated code and reducing the number of subclasses)

The class diagram

Application scenarios

Extend the functionality of a class or add additional responsibilities to a class

advantages

1. Comply with the Open Closed Principle

2. To extend functionality to an object without changing the original object

3. Use different combinations to achieve different effects

The point to summarize

  • By adopting a combination rather than inheritance approach, the Decorator pattern implements the ability to dynamically extend the functionality of an object at run time, and to extend as many functions as needed. Avoid the “poor flexibility” and “multiple subclass derivation problem” caused by inheritance.
  • The Decorator class inherits the same interface as the Component class, but the Decorator class uses another Component class. The Decorator class inherits the same interface as the Component class, but the Decorator class uses another Component class
  • The purpose of the Decorator pattern is not to solve the problem of “multiple inheritance derived from multiple subclasses.” The point of the application of the Decorator pattern is to solve the problem of “extension of the main class in multiple problem directions” — in the sense of “decoration.

Go language code implementation

Project directory

Decorator.go

Package Decorator import "FMT" type Component interface {Operate()} 1 type component1 struct {} func (C1 * component1) Operate() {fmt.println (" C1 ")} Decorator interface {Component Do() // This is an extra method} // Implements a specific Decorator type Decorator1 struct {C Component} func (D1) *Decorator1) Do() {fmt.println (" Decorator1 ")} func (d1 *Decorator1) Operate() {d1.do () d1.c.opperate ()}

Decorator_test.go

package Decorator import "testing" func TestCompontent1_Operate(t *testing.T) { c1 := &Compontent1{} c1.Operate() } func  TestDecorator1_Operate(t *testing.T) { d1 := &Decorator1{} c1 := &Compontent1{} d1.c = c1 d1.Operate() }