java 设计模式 -- 装饰者模式

179 阅读2分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

1.装饰者模式的理解

装饰器模式(Decorator Pattern):允许其动态的向一个现有的对象中添加一些新的功能,同时不改变它的结构,是一种结构型设计模式。 装饰者模式和继承都是为了扩展对象的功能,但是它比继承更有弹性,我们可以通过不同的装饰方式,得到更为丰富的装饰结果,满足开闭原则。

  1. 抽象构件角色(Component):定义一个对象接口或抽象类,可以动态的给它添加功能。
  2. 具体构件角色(ConcreteComponent):实际被添加功能的类。
  3. 抽象装饰者角色(Decorator):实现了Component,用来扩展Component功能的抽象类或接口。
  4. 具体装饰者角色(ConcreteDecorator):Decorator的具体实现类。

2.uml 类图

image.png

大家注意观察,抽象装饰者(Decorator)有一个属性是Component类型的,且它本身实现了Component,这就是装饰者模式的基本结构,至于为什么要这样,我会在下面的代码中给大家说明。

3.代码演示

这里代码的话,就直接借用尚硅谷课程中讲的咖啡馆点餐的例子了

image.png

  1. 抽象构件角色:通俗来讲可以理解为我们要装饰对象的抽象类

image.png

2.具体构件角色:我们要装饰对象的具体类,比如我们在点咖啡时,可能会加一些别的,牛奶,巧克力等别的小料。而咖啡就是我们需要具体装饰的对象。

image.png 他这里为了更方面扩展,多写了一层coffee的子类,这个可以根据我们的业务需求自己来决定

image.png

3.抽象装饰者角色:这可以类比我们上面说的要加的小料的抽象类

image.png

4.具体装饰者角色:即我们具体要加的小料。比如牛奶和巧克力都属于具体的小料

image.png

image.png

6.演示:

image.png

image.png 我们可以发现,这种模式下,我们可以按照自己的需求给 具体构件角色(咖啡),添加不同的小料(功能),符合开闭原则,易于扩展,无需修改原来的代码。

4.应用案例

在jdk中InputSream中就是用了装饰者模式

image.png

  • InputStream 是抽象类,类似我们前面讲的 Drink
  • FileInputStream 是InputStream 子类,类似我们前面的LongBlack
  • FilterInputStream是InputStream 子类:类似我们前面的Decorator 修饰者
  • DataInputStream 是FilterInputStream 子类,具体的修饰者,类似前面的Milk
  • FilterInputStream 类有protected volatile InputStream in; 即含被装饰者

大家可以自己研究研究源码。