GO设计模式——11、装饰器模式(结构型)

目录

[装饰器模式(Decorator Pattern)](#装饰器模式(Decorator Pattern))

装饰器模式的核心角色:

优缺点

使用场景

代码实现


装饰器模式(Decorator Pattern)

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

装饰器模式的核心角色

  • 抽象组件(Component):定义了对象的接口,可以是一个抽象类或接口。
  • 具体组件(ConcreteComponent):实现了抽象组件的接口,是被装饰的对象。
  • 装饰器(Decorator):维持一个指向抽象组件对象的引用,并实现了抽象组件的接口。
  • 具体装饰器(ConcreteDecorator):具体的装饰器对象,用于扩展具体组件的功能。

优缺点

(1)优点:

  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

(2)缺点:多层装饰比较复杂。

使用场景

  • 扩展一个类的功能。
  • 动态增加功能,动态撤销。

代码实现

Go 复制代码
package main

import (
    "fmt"
)

// 抽象组件:咖啡接口
type Coffee interface {
    GetDescription() string
    GetCost() float64
}

// 具体组件:原味咖啡
type PlainCoffee struct{}

func (c *PlainCoffee) GetDescription() string {
    return "Plain Coffee"
}

func (c *PlainCoffee) GetCost() float64 {
    return 1.0
}

// 装饰器:配料装饰器
type IngredientDecorator struct {
    coffee    Coffee
    extraCost float64
    extraDesc string
}

func (d *IngredientDecorator) GetDescription() string {
    return d.coffee.GetDescription() + ", " + d.extraDesc
}

func (d *IngredientDecorator) GetCost() float64 {
    return d.coffee.GetCost() + d.extraCost
}

// 具体装饰器:牛奶装饰器
type MilkDecorator struct {
    IngredientDecorator
}

func NewMilkDecorator(coffee Coffee) *MilkDecorator {
    return &MilkDecorator{
       IngredientDecorator{
          coffee:    coffee,
          extraCost: 0.5,
          extraDesc: "Milk",
       },
    }
}

// 具体装饰器:糖浆装饰器
type SyrupDecorator struct {
    IngredientDecorator
}

func NewSyrupDecorator(coffee Coffee) *SyrupDecorator {
    return &SyrupDecorator{
       IngredientDecorator{
          coffee:    coffee,
          extraCost: 0.3,
          extraDesc: "Syrup",
       },
    }
}

func main() {
    coffee := &PlainCoffee{}
    fmt.Println("Coffee:", coffee.GetDescription(), "Cost:", coffee.GetCost())

    coffeeWithMilk := NewMilkDecorator(coffee)
    fmt.Println("Coffee with Milk:", coffeeWithMilk.GetDescription(), "Cost:", coffeeWithMilk.GetCost())

    coffeeWithMilkAndSyrup := NewSyrupDecorator(coffeeWithMilk)
    fmt.Println("Coffee with Milk and Syrup:", coffeeWithMilkAndSyrup.GetDescription(), "Cost:", coffeeWithMilkAndSyrup.GetCost())
}
相关推荐
明月_清风3 小时前
加密解密系统完全指南:原理剖析与 Go 实践
后端
小江的记录本4 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven
冬奇Lab5 小时前
每日一个开源项目(第105篇):Twenty - 跳出 Salesforce 的圈套,定义现代开源 CRM
前端·后端·开源
鹏北海-RemHusband5 小时前
Go 语言进阶笔记 — 面向 JS/TS 前端开发者
笔记·golang
ServBay6 小时前
月之暗面 Kimi Code 0.4.0 发布,终端 AI 编码助手全面采用 TypeScript,实现毫秒级启动
后端·aigc·ai编程
小江的记录本6 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
小江的记录本6 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:G1:Region分区、Mixed GC、回收流程、适用场景(高频)(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·spring cloud·面试
欧雷殿7 小时前
从「吸引子引导工程」看我的「一人公司」实践
前端·人工智能·后端
卷无止境8 小时前
用一个电影院售票厅,把 SimPy 的条件事件讲透
后端