开发者学堂课程【Scala 核心编程 - 进阶:咖啡店的项目引出装饰者模式】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/610/detail/9138
咖啡店的项目引出装饰者模式
内容介绍:
一、装饰者模式
二、方案1-较差的方案
三、方案1-小结与分析
四、方案2-较好的方案
五、方案2的问题分析
六、体系图
七、装饰者模式原理
讲解的内容,首先是设计模式,还有示范型上下界,视图界定上下文界定还有协变逆变不变。
一、装饰者模式(Decorator)
看一个项目需求
咖啡馆订单系统项目(咖啡馆):
1)咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)
2)调料:Milk、Soy(豆浆)、Chocolate
3)要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
4)使用OO(面向对象)的来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖啡+调料组合。
比如说要点一份意大利浓咖啡,然后要求加一份牛奶,然后去计算价格,或者是点了一份美式咖啡,还要加两份巧克力,然后去算总的价格。
二、方案1-较差的方案
先抽象出来一个类叫 drink,不管是什么样单品它都是饮料,有一个描述为description,Cost 是计算费用,较差的方案就是单品单独设计一个类,比如有一个人再点一份意大利咖啡,她说她想加一份牛奶,这就成为了一个新的组合,如果espresso 再加一份牛奶和豆浆,就又成为了一个类,这样会出现类爆炸现象,现在单品咖啡有四个,调料有三种,一个单品就会对应七个类,加上单品本身就有八种,然后再乘以四,就有32种可能,就会出现类爆炸。
三、方案1-小结与分析
1) Drink 是一个抽象类,表示饮料
2) description 就是描述,比如咖啡的名字等3) cost就是计算费用,是一个抽象方法
4) Decaf 等等就是具体的单品咖啡,继承Drink,并实现cost方法
5) Espresso&&Milk 等等就是单品咖啡+各种调料的组合,这个会很多..
6)这种设计方式时,会有很多的类,并且当增加一个新的单品咖啡或者调料时,类的数量就会倍增(类爆炸)
四、方案2-较好的方案
前面分析到方案1因为咖啡单品+调料组合会造成类的倍增,因此可以做改进,将调料内置到 Drink 类,这样就不会造成类数量过多。从而提高项目的维护性(如图)
说明:
milk,soy,choclate 可以设计为 Boolean,表示是否要添加相应的调料.
这样设计过后,类只要有四个就可以了,将来在设计的时候,比如说想要一份豆浆,直接在cost里面判断有没有就可以了。
五、方案2的问题分析
1)方案2可以控制类的数量,不至于造成过多的类。
2)在增删调料种类时,代码维护量仍然很大。如果将来drink增加了一份调料,比如说是豆腐脑,那么就需要修改drink,就会很麻烦,这就违反了ocp原则,因为再加一个单品的时候,代码的变化是很大的。
3)考虑到添加多份调料时,可以将Boolean改成Int
六、体系图
一个项目的类的体系图,里面有很多的类,包括里面有继承关系。
1.在开发中要求尽量的遵守 ocp
开闭原则:
将来如果要增加一个功能,这些代码尽量都不要去进行修改,可以直接加一个类进去,把新类加进去功能就增加了,整个体系是没有发生变化的。
2. ocp (开闭原则):通过增加新的类,来扩展功能.
开闭原则:开:指的是功能扩展开放,闭:不要去修改已有的代码
七、装饰者模式原理
1)装饰者模式就像打包一个快递
主体:比如:陶瓷、衣服
>包装:比如:报纸填充、塑料泡沫、纸板、木板
2) Component
主体:比如类似前面的 Drink
3) ConcreteComponent 和 Decorator
ConcreteComponent:具体的主体,
比如前面的各个单品咖啡
Decorator:装饰者,比如各调料.
4)在如图的 Component 与 ConcreteComponent 之间,如果
ConcreteComponent 类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象层一个类。