设计模式––装饰模式

概述

装饰模式主要用来动态的拓展现有的功能。主要包含四个角色,抽象构件 Component,具体构件 ConcreteComponent,抽象装饰类 Decorator,具体装饰类 ConcreteComponent。具体类图可参考类图小节。当需要给已有的具体构件拓展新功能时,增加具体装饰类即可,很灵活。

核心思想

有一个最基础的抽象构件 Component 类,ConcreteComponent 和 Decorator 都继承自 Component,并且 Decorator 聚合 Component。一般情况下,装饰者的构造器需要传入被装饰对象。

类图

在这里插入图片描述
从类图可知,ComponentA 和 Decorator 都继承自 Component,并且Decorator 聚合了 Component 类,那么理论上 Component 的子类都能用 Decorator 的子类来装饰,那么拓展新功能时,只需要拓展具体的 Decorator 就可以了,如 DecoratorC、DecoratorD 等等。

优缺点

  • 优点
    动态的给具体构件拓展新功能,解决了继承可能带来的类膨胀问题。
  • 缺点
    从使用上看,装饰类会一层一层的将被装饰类包起来,当出现问题时,刚好问题点在某个比较深的装饰类,那调试查找问题会比较麻烦。

代码实现

Component

public abstract class Component {
    public abstract void hello();
}

ComponentA

public class ComponentA extends Component {
    @Override
    public void hello() {
        System.out.println("ComponentA#hello()");
    }
}

Decorator

public abstract class Decorator extends Component {
    protected Component component;
    public Decorator(Component component) {
        this.component = component;
    }
}

DecoratorA

public class DecoratorA extends Decorator {
    public DecoratorA(Component component) {
        super(component);
    }

    @Override
    public void hello() {
        System.out.println("DecoratorA#hello()");
        this.component.hello();
    }
}

DecoratorB

public class DecoratorB extends Decorator {
    public DecoratorB(Component component) {
        super(component);
    }

    @Override
    public void hello() {
        System.out.println("DecoratorB#hello()");
        this.component.hello();
    }
}

TestDecorator

public class TestDecorator {
    public static void main(String[] args) {
        Component component = new ComponentA(); //待装饰对象

        component = new DecoratorA(component);  //使用 DecoratorA 对 component 进行装饰
        component = new DecoratorB(component);  //使用 DecoratorB 对 component 进行装饰

        component.hello();
    }
}

运行 TestDecorator 的 main 方法,输出如下,

DecoratorB#hello()
DecoratorA#hello()
ComponentA#hello()

哪里见过这种模式?

在 JDK 中,java.io.Reader,java.io.InputStreamReader,java.io.BufferedReader, 这三个类及它们子类的实现上使用了装饰模式,其类图如下,
在这里插入图片描述
这个类图是不是很眼熟,没错,这就是上面的装饰模式的实现类图。可以看到 Reader 是一个最基础的类,InputStreamReader 在这里为被装饰者,BufferedReader 是装饰者。BufferedReader 构造时需要传入 Reader 对象,构造方法实现如下,
在这里插入图片描述
即 BufferedReader 聚合了 Reader 对象。

总结

装饰模式主要用来给对象动态拓展功能,在项目开发过程中非常灵活,当需要增加或删除某个功能时,只需要加上或去掉对应的装饰类即可,从装饰模式的类图可以一目了然整体的模式设计。
在 JDK 中也有很多地方用到装饰模式,例如 java.io.Reader 的实现。

下面是公众号,欢迎扫描二维码,感谢关注和支持!
公众号名称:ToSimple
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ToSimpleL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值