设计模式解密:装饰器模式的终极指南(PHP/Go双实现)
一、什么是装饰器模式?
装饰器模式(Decorator Pattern) 是一种结构型设计模式,用于动态地为对象添加额外功能。装饰器模式的核心思想是通过组合而非继承来扩展对象的功能,遵循开闭原则(对扩展开放,对修改关闭)。
核心角色:
组件接口(Component):定义对象和装饰器的通用接口
具体组件(Concrete Component):实现基本功能的原始对象
装饰器基类(Decorator):持有组件引用并实现组件接口
具体装饰器(Concrete Decorator):添加具体扩展功能
二、适用场景
✅ 需要动态添加/撤销对象功能
✅ 不适合使用继承扩展功能
✅ 需要组合多种扩展功能
✅ 需要遵循开闭原则
三、PHP实现方案
1. 基础实现(咖啡加料示例)
interface Coffee {
public function cost(): float;
public function description(): string;
}
class SimpleCoffee implements Coffee {
public function cost(): float {
return 2.0;
}
public function description(): string {
return "Simple coffee";
}
}
abstract class CoffeeDecorator implements Coffee {
protected $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
abstract public function cost(): float;
abstract public function description(): string;
}
class MilkDecorator extends CoffeeDecorator {
public function cost(): float {
return $this->coffee->cost() + 0.5;
}
public function description(): string {
return $this->coffee->description() . ", milk";
}
}
class SugarDecorator extends CoffeeDecorator {
public function cost(): float {
return $this->coffee->cost() + 0.2;
}
public function description(): string {
return $this->coffee->description() . ", sugar";
}
}
// 使用示例
$coffee = new SimpleCoffee();
$coffee = new MilkDecorator($coffee);
$coffee = new SugarDecorator($coffee);
echo $coffee->description(); // 输出:Simple coffee, milk, sugar
echo $coffee->cost(); // 输出:2.7
2. 进阶实现(带链式调用)
trait DecoratorTrait {
protected $component;
public function wrap(Component $component): Component {
$this->component = $component;
return $this;
}
}
class BoldDecorator implements Component {
use DecoratorTrait;
public function render(): string {
return "<b>" . $this->component->render() . "</b>";
}
}
class ItalicDecorator implements Component {
use DecoratorTrait;
public function render(): string {
return "<i>" . $this->component->render() . "</i>";
}
}
// 使用示例
$text = new TextComponent("Hello World");
$decoratedText = (new BoldDecorator())->wrap(
(new ItalicDecorator())->wrap($text)
);
echo $decoratedText->render(); // 输出:<b><i>Hello World</i></b>
四、Go实现方案
1. 基础实现(数据流处理)
package main
import "fmt"
type DataProcessor interface {
Process(data string) string
}
type BasicProcessor struct{}
func (p *BasicProcessor) Process(data string) string {
return data
}
type ProcessorDecorator struct {
processor DataProcessor
}
func (d *ProcessorDecorator) Process(data string) string {
return d.processor.Process(data)
}
type EncryptDecorator struct {
ProcessorDecorator
}
func (e *EncryptDecorator) Process(data string) string {
base := e.ProcessorDecorator.Process(data)
return "Encrypted(" + base + ")"
}
type CompressDecorator struct {
ProcessorDecorator
}
func (c *CompressDecorator) Process(data string) string {
base := c.ProcessorDecorator.Process(data)
return "Compressed(" + base + ")"
}
// 使用示例
func main() {
processor := &BasicProcessor{}
// 装饰器组合
encryptedProcessor := &EncryptDecorator{ProcessorDecorator{processor}}
compressedEncryptedProcessor := &CompressDecorator{ProcessorDecorator{encryptedProcessor}}
result := compressedEncryptedProcessor.Process("sensitive data")
fmt.Println(result) // 输出:Compressed(Encrypted(sensitive data))
}
2. 进阶实现(HTTP中间件)
package main
import "fmt"
type Handler func(string)
type Middleware func(Handler) Handler
func LoggingMiddleware(next Handler) Handler {
return func(req string) {
fmt.Println("Logging request:", req)
next(req)
}
}
func AuthMiddleware(next Handler) Handler {
return func(req string) {
fmt.Println("Authenticating...")
next(req)
}
}
func main() {
handler := func(req string) {
fmt.Println("Processing request:", req)
}
// 装饰器链
decoratedHandler := LoggingMiddleware(
AuthMiddleware(handler),
)
decoratedHandler("GET /api/data")
// 输出:
// Logging request: GET /api/data
// Authenticating...
// Processing request: GET /api/data
}
五、关键实现差异对比
六、模式优缺点分析
👍 优点:
动态扩展功能:运行时添加/移除功能
避免继承爆炸:通过组合实现灵活扩展
遵循开闭原则:无需修改已有代码
功能组合灵活:支持任意顺序组合装饰器
👎 缺点:
增加代码复杂度:引入多个小类
调试困难:多层装饰可能难以追踪
初始化复杂:多层装饰器嵌套初始化
七、实际应用案例
1. Web中间件
// PHP中间件示例
$app = new App();
$app->addMiddleware(new AuthMiddleware());
$app->addMiddleware(new LoggingMiddleware());
$app->handleRequest();
2. 数据流处理
// Go数据流处理
processor := NewBaseProcessor()
processor = NewEncryptDecorator(processor)
processor = NewCompressDecorator(processor)
result := processor.Process(data)
3. GUI组件装饰
// PHP UI组件示例
$textBox = new TextBox();
$textBox = new BorderDecorator($textBox);
$textBox = new ScrollDecorator($textBox);
$textBox->render();
八、与代理模式的区别
九、总结
装饰器模式是动态扩展对象功能的利器,通过组合而非继承的方式,实现了灵活的功能扩展。无论是PHP的类装饰器还是Go的函数式中间件,装饰器模式都能显著提升代码的可维护性和扩展性。
在下一篇文章中,我们将探讨 外观模式 及其在简化复杂系统接口中的应用。敬请期待!
下一篇预告:设计模式系列(十)——外观模式:复杂系统的简化之门
License:
CC BY 4.0