作者TKB5566 (蔡英文还我七天假!!)
看板java
标题Re: [问题] 装饰者模式的原理
时间Sun Apr 16 19:04:36 2023
目前对装饰者模式产生的原因理解如下:
若以人穿衣服,或是饮料店对饮料加料为例,人跟饮料可以是最上层的父类别
衣服可以有很多种,饮料要加的料也可以有很多种,若是以继承的方式来给人穿衣服
或是给饮料加料,这样的话:
人+一种衣服是一种子类别,饮料+一种料也是一种子类别。
这样的话很多种衣服很多种料,就会有很多种子类别。
更不要说很多种衣服、很多种料各自还可以组合出不同子类别。
所以很明显,子类别数量会过於庞大。
而且人+一种衣服、饮料+一种料,按照逻辑,衣服跟料都是可选择的,顺序不固定的,
若用继承方式去扩充人和饮料的话,那就是
把穿衣服跟加料的顺序写死。这就完全
不符合人类穿衣或给饮料加料的逻辑,也就是说完全不合理。
这是一个原因。
另一个原因,以麦当劳主餐配副餐,组成套餐为例。主餐配副餐形成套餐,
看似可以用继承方式来描述,也就是主餐为父类别,套餐继承主餐类别并加上副餐,
形成子类别。但是
主餐往往不只一种,这样的话变成
有多种主餐,套餐要继承主餐就会变成是多重继承。
因此在某些需求下,会变成多重继承,这是Java程式必须避免的现象。
再来,若是坚持要以继承来实作以上的例子,继承可能会有很多层,例如饮料加了
很多料,其实就是子类别有好几层,下一层类别都包含了上一层类别,这样的话,
若是要计算「加了很多料的饮料」的价格,
计算的method必须层层呼叫到最上层的类别,
取出原始饮料的价格後,又层层返回到最下层的,加了很多料的类别,这样才能计算出
「加了很多料的饮料」的价格,也就是说类别之间相依性很高,而相依性高正好也是
Java程式必须避免的问题。
-----------------------------------
所以总结以上的说法,可以归纳出使用继承来给类别扩充功能,会有三个问题:
1
子类别扩充顺序是写死的,这样要把所有扩充顺序都列出,子类别会过多。
2
单一继承不能处理所有需求,变成不得不多重继承。
3
程式之间相依性过高。
-----------------------------------
为了解决使用继承来给类别扩充功能,所带来的三个问题,就希望可以:
针对第1个问题,给类别扩充功能必须可以依需求来调整扩充的顺序。
针对第2个问题,做到不使用多重继承也能做出多重继承的效果;
而介面正好可以多重实作,所以这里可以考虑以介面代替类别来进行实作。
针对第3个问题,就是要降低类别之间的相依性,这也可以藉由介面来实现。
於是装饰者模式,就这样被设计出来了。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 49.216.165.102 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1681643078.A.A30.html
1F:推 brt: 很清楚 04/22 10:41
2F:推 thewindjuei: 感谢分享说明 04/28 12:41