Golang学习笔记_33——桥接模式
Golang学习笔记_34——组合模式
Golang学习笔记_35——代理模式
文章目录
- 一、核心概念
- 1. 定义
- 2. 解决的问题
- 3. 核心角色
- 4. 类图
- 二、特点分析
- 三、适用场景
- 1. 流处理系统
- 2. GUI组件增强
- 3. 中间件开发
- 四、代码示例(Go语言)
- 五、与其他模式对比
- 六、总结
一、核心概念
1. 定义
装饰器模式(Decorator Pattern)是一种结构型设计模式,允许在不修改原始对象结构的情况下,通过创建包装对象动态地扩展对象的功能。它通过嵌套组合替代继承,实现功能的灵活叠加。
2. 解决的问题
- 动态扩展功能:运行时添加/移除对象行为
- 避免类爆炸:替代多层继承导致的子类膨胀
- 保持接口一致性:装饰器与原始对象实现相同接口
3. 核心角色
- Component(抽象组件)
定义对象接口(如Coffee
接口声明Cost()
方法) - ConcreteComponent(具体组件)
实现基础功能的对象(如原味咖啡) - Decorator(装饰器基类)
持有组件引用并实现相同接口(可选抽象类) - ConcreteDecorator(具体装饰器)
添加具体扩展功能(如牛奶、糖装饰器)
4. 类图
二、特点分析
优点
- 动态扩展:运行时灵活添加/移除功能
- 单一职责:每个装饰器只负责一个功能扩展
- 开闭原则:无需修改已有代码即可扩展
缺点
- 复杂度增加:多层装饰导致调用链较长
- 对象数量膨胀:可能产生大量小对象
- 初始化繁琐:需要逐层包装对象
三、适用场景
1. 流处理系统
- 基础组件:文件流
- 装饰器:加密流、缓冲流、压缩流
- 操作:动态组合流处理链(如
加密(缓冲(文件流))
)
2. GUI组件增强
- 基础组件:文本框
- 装饰器:边框装饰、滚动条装饰、阴影装饰
- 操作:动态叠加视觉效果
3. 中间件开发
- 基础组件:HTTP处理器
- 装饰器:日志记录、权限校验、缓存处理
- 操作:按需组合中间件链
四、代码示例(Go语言)
package decoratordemo
import "fmt"
// 抽象组件
type Coffee interface {
Cost() float64
Description() string
}
// 具体组件:原味咖啡
type PlainCoffee struct {
}
func (p *PlainCoffee) Cost() float64 {
return 2.0
}
func (p *PlainCoffee) Description() string {
return "原味咖啡"
}
// 装饰器基类(可选)
type CoffeeDecorator struct {
coffee Coffee
}
func (d *CoffeeDecorator) Cost() float64 {
return d.coffee.Cost()
}
func (d *CoffeeDecorator) Description() string {
return d.coffee.Description()
}
// 具体装饰器:牛奶
type MilkDecorator struct {
CoffeeDecorator
}
func (m *MilkDecorator) Cost() float64 {
return m.CoffeeDecorator.Cost() + 0.5
}
func (m *MilkDecorator) Description() string {
return m.CoffeeDecorator.Description() + ", 加牛奶"
}
func NewMilkDecorator(coffee Coffee) *MilkDecorator {
return &MilkDecorator{CoffeeDecorator{coffee}}
}
// 具体装饰器:糖
type SugarDecorator struct {
CoffeeDecorator
}
func (s *SugarDecorator) Cost() float64 {
return s.CoffeeDecorator.Cost() + 0.3
}
func (s *SugarDecorator) Description() string {
return s.CoffeeDecorator.Description() + ", 加糖"
}
func NewSyrupDecorator(coffee Coffee) *SugarDecorator {
return &SugarDecorator{CoffeeDecorator{coffee}}
}
func test() {
// 原味咖啡
coffee := &PlainCoffee{}
fmt.Printf("%s → $%.2f\n", coffee.Description(), coffee.Cost())
milkCoffee := NewMilkDecorator(coffee)
fmt.Printf("%s → $%.2f\n", milkCoffee.Description(), milkCoffee.Cost())
syrupMilkCoffee := NewSyrupDecorator(milkCoffee)
fmt.Printf("%s → $%.2f\n", syrupMilkCoffee.Description(), syrupMilkCoffee.Cost())
}
输出结果:
=== RUN Test_test
原味咖啡 → $2.00
原味咖啡, 加牛奶 → $2.50
原味咖啡, 加牛奶, 加糖 → $2.80
--- PASS: Test_test (0.00s)
PASS
五、与其他模式对比
模式 | 核心目标 | 关键区别 |
---|---|---|
适配器 | 接口转换 | 主要解决接口不兼容问题 |
代理 | 控制访问 | 保持接口相同,增强访问控制 |
组合 | 处理树形结构 | 关注部分-整体层次结构 |
六、总结
装饰器模式通过嵌套包装的方式,实现了以下核心价值:
- 动态扩展:运行时灵活添加功能
- 避免继承:通过组合替代多层继承
- 接口透明:客户端无需感知装饰过程
在Go语言中实现时需注意:
- 利用接口实现多态
- 通过结构体嵌套实现装饰器链
- 保持装饰器与原始组件接口一致