写点什么

结构型设计模式 - 装饰器 Decorator

作者:菜皮日记
  • 2023-09-08
    北京
  • 本文字数:1294 字

    阅读完需:约 4 分钟

简介

装饰器模式可以在目标对象原有的基础上,添加其他功能,实现动态增强。

需要明确的是代理模式也有类似的作用,而装饰器模式与代理模式最大的不同在于,装饰器模式下,对目标对象设置增强的权利交给了 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))
复制代码


用户头像

菜皮日记

关注

全干程序员 2018-08-08 加入

还未添加个人简介

评论

发布
暂无评论
结构型设计模式-装饰器 Decorator_设计模式_菜皮日记_InfoQ写作社区