java中装饰器_Java中的装饰器模式

从概念上讲,是在实现一个抽象内容的同时,以增强或扩展其功能为目的,对它进行一层层,可互相嵌套式的,能灵活添加或去除且顺序可变的包装。

从UML类图结构上来说,它是类的多态特性的扩展。除了‘具体构建对象’对‘抽象构建接口’的独立实现外,在‘装饰器(接口实现类)’构建时还允许将‘抽象构建接口’作为构建方法的入参,被‘装饰器’当作成员属性持有,最终由‘实际的装饰器对象’继承‘装饰器’来实现具体的功能,并允许‘实际的装饰器对象’可以相互嵌套已实现功能的叠加和扩展。

339a719e2b7e

图示:装饰器模式的UML类图结构

图例说明:

Component:抽象构建接口。描述需要抽象的内容

ConcreteComponent:独立的构建对象。通过Java泛化来实现抽象构建接口。

Decorator:装饰器抽象父类。所有的子装饰器对象的统一父类,需要内部持有一个Component并在构建方法中入参这个Component,并同时实现Component接口。

ConreteDecoratorA、ConreteDecoratorB:实际的装饰器对象。具体负责扩展Component的功能。

Java中如何使用装饰器模式

日常生活中的饮品种类多不胜数,但是它们的配料内容大部分是相同的,比如绿茶就是开水冲茶叶,奶茶就是已经制作好的绿茶中添加鲜牛奶,当然奶茶也可以先煮鲜牛奶,再放入茶叶。像生活中这类制作顺序可灵活变化的事物,就可以用装饰器模式来描述。

339a719e2b7e

图示:用修饰器模式来表示饮品

装饰器模式中都有一个同源的接口类(抽象构建接口类),描述需要构想的内容。在这里用IDrink这个接口来描述‘饮品’这一抽象类。

339a719e2b7e

装饰器模式中还需要一个统一的装饰器抽象父类,这里用DrinkDecorator抽象类来代表:

339a719e2b7e

例子中WaterDrink是直接用继承的方式实现IDrink,这里作为最地基础的原料(饮品当然水是最基本的嘛)。

339a719e2b7e

之后的TeaDrink(茶饮)、MilkyDrink(奶饮)、FruitDrink(果饮)都是用WaterDrink来制作的(从UML上来说,就是内部持有IDrink的实现类)

339a719e2b7e

339a719e2b7e

339a719e2b7e

就像例子开头举得奶茶的例子,就可以用UML图做如下表达:

339a719e2b7e

图示:奶茶的UML表达

代码实现如下:

339a719e2b7e

执行结果:

成分配料:饮用水;高品质茶叶;鲜牛奶;

制作方法:->添加饮用水->开水煮茶叶->混合新鲜牛奶

同理,如果想更复杂一些,比如水果味奶茶,可以用UML图描述如下:

339a719e2b7e

图示:果味奶茶UML表达

代码如下,结果就不重复了

339a719e2b7e

Java中的装饰器模式的优缺点

灵活的组合是最大的优点。装饰器模式与类的泛化都是对类功能的扩展,但使用装饰器模式,从代码维护上来讲,可以更简单的为对象“添加一个装饰(包裹一层功能外衣)”,“去除一个装饰(脱下一层)”,顺序也可以方便的调整,可以通过不同的组合实现各色各样的业务场景。

缺点也很明显,它会产生很多的装饰对象。如果不加以设计和充分描述,其他程序员会较难理解并使用各个装饰对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值