Bootstrap

【设计模式】创建型模式之装饰器模式(组成、步骤、优缺点、场景)

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持原类方法签名完整性的前提下,提供了额外的功能。

装饰器模式的主要组成

  1. Component(组件):定义了对象的接口,可以给这些对象动态地添加职责。
  2. Concrete Component(具体组件):定义了对象的一个具体实现。
  3. Decorator(装饰器):持有一个组件对象的引用,并实现与组件相同的接口。
  4. Concrete Decorator(具体装饰器):负责给组件添加新的功能。

装饰器模式的实现步骤

  1. 定义组件接口:这个接口规定了可以装饰的对象的类型。
  2. 创建具体组件:实现组件接口,定义一个具体的对象。
  3. 创建装饰器抽象类:实现组件接口,并持有一个组件对象的引用。
  4. 创建具体装饰器:继承装饰器抽象类,实现具体装饰逻辑。

装饰器模式的优点

  1. 扩展性:可以在不修改原有对象代码的前提下,通过添加新的装饰器来扩展功能。
  2. 灵活性:可以在运行时动态地添加或去除职责。
  3. 低耦合性:装饰器和具体组件之间是松耦合的,增加新的装饰器不需要修改组件代码。

装饰器模式的缺点

  1. 过度使用:如果过度使用装饰器模式,可能会导致系统变得复杂,难以理解。
  2. 性能问题:装饰器可能会增加一些性能开销,因为每次装饰都涉及到额外的对象创建和方法调用。

装饰器模式的使用场景

  • 当需要在不修改对象源代码的情况下,给对象添加新的功能时。
  • 当需要动态地给一个对象添加功能时,这些功能可以是临时的。

package main

import "fmt"

// Component 定义了对象的接口,可以给这些对象动态地添加职责
type Component interface {
    Operation() string
}

// ConcreteComponent 定义了对象的一个具体实现
type ConcreteComponent struct{}

func (c *ConcreteComponent) Operation() string {
    return "ConcreteComponent"
}

// Decorator 持有一个Component对象的引用,并实现与Component相同的接口
type Decorator struct {
    Component Component
}

func (d *Decorator) Operation() string {
    return d.Component.Operation()
}

// ConcreteDecorator 负责给Component添加新的功能
type ConcreteDecoratorA struct {
    Decorator
}

func (cda *ConcreteDecoratorA) Operation() string {
    return cda.Decorator.Operation() + " ConcreteDecoratorA"
}

// ConcreteDecoratorB 另一个装饰器,添加不同的功能
type ConcreteDecoratorB struct {
    Decorator
}

func (cdb *ConcreteDecoratorB) Operation() string {
    return cdb.Decorator.Operation() + " ConcreteDecoratorB"
}

func main() {
    // 创建具体组件
    component := &ConcreteComponent{}

    // 动态添加装饰器
    decoratorA := &ConcreteDecoratorA{Decorator{Component: component}}
    decoratorB := &ConcreteDecoratorB{Decorator: Decorator{Component: decoratorA}}

    // 输出装饰后的结果
    fmt.Println(component.Operation())           // 输出 ConcreteComponent
    fmt.Println(decoratorA.Operation())         // 输出 ConcreteComponent ConcreteDecoratorA
    fmt.Println(decoratorB.Operation())         // 输出 ConcreteComponent ConcreteDecoratorA ConcreteDecoratorB
}

装饰器模式主要用于解决继承关系过于复杂的问题,通过组合来替代继承,主要作用是给原始类添加增加功能。

实现方式是继承或接口,如果装饰类的方法大部分和原类相同,用继承。

和代理模式的区别:代码形式上几乎没有区别。代码模式主要是给原始类添加无关的功能,装饰器模式主要是给原始类增强功能,添加的功能都是有关联的。

Go设计模式08-装饰器模式

第17篇-装饰器模式

;