结构型设计模式-装饰器 Decorator
简介
装饰器模式可以在目标对象原有的基础上,添加其他功能,实现动态增强。
需要明确的是代理模式也有类似的作用,而装饰器模式与代理模式最大的不同在于,装饰器模式下,对目标对象设置增强的权利交给了 client,即 client 先要得到目标对象,之后决定要用哪些装饰器给目标对象增强,一层层嵌套。
具体来说比如 Java 的 IO 操作,一般需要先 new 一个目标对象 FileInputStream,之后将其作为参数传给 BufferedInputStream 即可实现有 buffer 增强功能 InputStream。
装饰器类和被装饰类应该实现同一接口,这样可以保证被装饰器增强后的类的调用方式与之前一直,且支持无限次装饰调用。
装饰器是典型的组合优于继承的例子,试想如果用继承来实现增强的话,每有一个增强项,都需要重写一个类,而支持多种增强项的类则需要继承多次。
角色
-
Component 接口
定义基本的操作
-
Decorator 装饰器
实现 Component 接口,增强代码所在
-
Wrappee/Concrete Component 被装饰的原始类
实现 Component 接口,是被装饰增强的原始类
类图
图中所示,Component 是共有的接口,Concrete Component 是被装饰的类,Concrete Decorators 装饰器类。装饰器类接收 Component 为参数,execute 方法即增强方法。
代码
interface Component
{
public function operation(): string;
}
class ConcreteComponent implements Component
{
public function operation(): string
{
return "ConcreteComponent";
}
}
class Decorator implements Component
{
protected $component;
public function __construct(Component $component)
{
$this->component = $component;
}
public function operation(): string
{
return $this->component->operation();
}
}
class ConcreteDecoratorA extends Decorator
{
public function operation(): string
{
return "ConcreteDecoratorA(" . parent::operation() . ")";
}
}
class ConcreteDecoratorB extends Decorator
{
public function operation(): string
{
return "ConcreteDecoratorB(" . parent::operation() . ")";
}
}
function clientCode(Component $component)
{
echo "RESULT: " . $component->operation() . "\n";
}
$simple = new ConcreteComponent();
echo "Client: I've got a simple component:\n";
clientCode($simple);
echo "\n";
$decorator1 = new ConcreteDecoratorA($simple);
$decorator2 = new ConcreteDecoratorB($decorator1);
echo "Client: Now I've got a decorated component:\n";
clientCode($decorator2);
output:
Client: I've got a simple component:
RESULT: ConcreteComponent
Client: Now I've got a decorated component:
RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))
本文由mdnice多平台发布
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!