装饰者模式介绍和咖啡店应用实例 | 学习笔记

简介: 快速学习装饰者模式介绍和咖啡店应用实例

开发者学堂课程【Scala 核心编程 - 进阶装饰者模式介绍和咖啡店应用实例学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/610/detail/9139


装饰者模式介绍和咖啡店应用实例


内容介绍

一、原理

二、设计方案

三、代码

四、举例

五、总结


一、原理

装饰者模式就像打包快递一样,例如在淘宝上买了陶瓷产品或者买了一件衣服,商家先用报纸或者塑料泡沫包裹,主体就是陶瓷或者衣服,主体叫 component,由主体引申出 concretecomponent,concrete 是混凝土的意思,decorator 就是装饰者,可以理解成各种调料,这样就形成新的关系,

在 component 和 creatcomponent 之间,可以设计缓冲层,也可以不设计, decorator 也会继承 drink,两者都成为了 component 的子类,就可以进行装饰。

比如 concrete 对应具体的主体,比如单品咖啡,而decorator认为是装饰者,因为喝咖啡可以不要调料,调料是可选的,装饰者是附着在上面的。

所谓装饰者就是动态的将新功能附加在对象上,在对象功能扩展方面,比继承更加的有弹性,装饰者也充分的体现出开闭原则。


二、设计方案

image.png

通过装饰者模式就有变化了,首先drink是抽象的,而单品咖啡可以独立出来,而decreator装饰者里面有各个调料。

说明:

Drink这个超类和前面基本一样;

Shortblack等单品咖啡的设计也和之前一样;

Decorator是装饰类,包含了被装饰的对象;

Decorator的cost费用要进行叠加,因为装饰者可以装饰,还可以继续装饰。

image.png

(1)有一份Milk+LongBlack【相当于是Milk装饰了

LongBlack】 Milk是装饰者,LongBlack是主体;

(2)使用 chocolate装饰了一份 Milk+LongBlack;

(3)使用 chocolate装饰 chocolate+LongBlack+Milk,层叠的进行装饰,当计算成本时要递归的计算,


三、代码

首先对照图

image.png

Drink 表示饮品,是抽象类,最主要抽象描述,因为饮品是个抽象的,所以是抽象方法,将计算成本的方法做成抽象方法,然后继承。

出现以下报错:

Package com.atguigu.chapter17.decorator.coffeebar.mycoffee

class Espresso extends coffee {

//使用主构造器

super.setDescription(“Espresso”)

super.setPrice(6.0f)

}

coffee 地方报错,因为在 component 和 concrete 之间做了一层缓冲层,因为从扩展性来说,将来可能咖啡店扩展了,除了有咖啡这种产品还有传统饮品,如果仅仅针对这个案例来说,可以不要,此处是为了扩展,意义并不大。

单品咖啡在装饰者设计模式中就是concrete:

packagecom. atguigu.chapter17.decorator .coffeebar.mycoffee

class Espresso extends Coffee {

super . setDescription("Espresso")

super . setPrice(6.0f)

}

decorator 是关键,是装饰者模式体现的价值:

class Decorator extends Drink {

private var obj: Drink =null

def this(obj: Drink) {

this.obj=obj

}

override def cost(): Float={

super . getprice()+obj.cost()

}

首先仍然继承 drink,object 是被装饰的, object可以是单品咖啡,也可以咖啡加调料的组合,计算成本实现了 COS 的方法,首先先得到自己的咖啡,然后递归的调用,因为是不停的装饰。

获取信息时,也要递归。chocolate 要继承 decorator,在巧克力里面放 drink,然后扩展它。放到体系里面,decorator 也是 drink 的子类,以此类推,牛奶也不停的往上继承。

使用时,直接调订单里面cost得到描述,因为无音咖啡继承coffee,而coffee又继承了 drink,订单一的价格就是三块钱,运行结果如下:

orde1 price: 3.0

order1 desc :Decaf 价格:3.0

如果需求是点一份longblack,并且加入两份巧克力代码如下:

Var order2:Drink=new Longblack

因为用装饰者模式,在定milk的时候,直接放进去即可,因为milk继承装饰者,所以就可以用decorator相应的方法,也把对象传给了decorator,decorator把对象交给了装饰者,一步一步传到decorator,

此时运行结果:

order2 price:7.0

order2 desc:Milk 价格:2.0&&LongBlack价格:5.0

假如还要再加两份巧克力和一份milk,结果如下:

order2 price:10.0

order2 desc:chocolate 价格:3.0&&Milk 价格:2.0&&LongBlack价格:5.0

如果还要再来一份咖啡,再包裹即可。当在目前基础上去增加新的饮品时,就不需要动整个类的体系结构了。

比如有一种新式的牛奶,复制一份即可,把名字或价格更改即可,价格也可以算出。如果单品咖啡再加一份,也是相同道理。如果需求特别复杂时就可以使用该设计模式。


四、举例

Java 中的 io 流里面有叫 fiilterinputstream,就是装饰者,inputstream就是被装饰者,

示意图如下:

image.png

如果想加入过滤的功能,继承之后然后把被装饰包裹,文件流也具有了过滤的功能,fiilterinputstream就是装饰者,而inputstream就是被装饰者。


五、总结

先提出需求,引起思考,需求是咖啡店有单品咖啡、调料,要求在扩展咖啡种类,用oo来计算不同种类咖啡的费用,可以单点可以组合。最原始的方法,会形成会出现类爆炸的情况。

image.png

第二种方案最大的问题就是将来会直接去修改代码,违反了ocp的原则,将来缺口会变得越来越大,应该尽量避免。

image.png

第三种方案是就是装饰者模式

image.png

在主体就是component,包装就是decorator,于是提出设计方案,先抽象出来一层,因为可能有很多子类,主体就是陶瓷或者衣服,主体叫component,由主体引申出concretecomponent,concrete是混凝土的意思,decorator就是装饰者,可以理解成各种调料。主体是最重要,装饰者是单品咖啡,装饰者就是动态的将新的功能附加在对象上,动态很重要,不需要改源代码,比继承更加的有弹性,充分利用递归的特性,也体现了开闭原则。先用装饰者设计模式设计方案如下:

image.png

相关文章
|
4月前
|
设计模式 Java
【惊天揭秘】Java编程绝技大曝光:接口、抽象类、静态类与非静态类的神秘面纱终被揭开!
【8月更文挑战第22天】Java支持面向对象编程,通过接口、抽象类、静态类(如枚举与工具类)及普通类实现设计原则。接口定义行为规范,允许多重继承;抽象类含未实现的抽象方法,需子类完成;静态类常为工具类,提供静态方法;普通类则实例化对象。恰当运用这些结构能提升程序质量。
44 2
|
4月前
|
设计模式
学会了这个设计模式,再也不是只会写if/else了
本文详细介绍了责任链设计模式(Chain of Responsibility Pattern),这是一种行为型设计模式,用于创建一个接收者对象的链,通过解耦请求的发送者和接收者,允许沿着链传递请求,直到某个接收者能够处理它。
学会了这个设计模式,再也不是只会写if/else了
|
7月前
|
设计模式 Java 数据库
二十三种设计模式全面解析-单例设计模式:解密全局独一无二的实例创造者
二十三种设计模式全面解析-单例设计模式:解密全局独一无二的实例创造者
|
设计模式 算法
策略设计模式介绍与应用实战
策略设计模式介绍与应用实战
71 0
|
设计模式 关系型数据库 Scala
咖啡店的项目引出装饰者模式 | 学习笔记
快速学习咖啡店的项目引出装饰者模式
咖啡店的项目引出装饰者模式 | 学习笔记
|
C++
爱上c++的第二天:类和对象的三大特性-封装
对只写权限,我们可以检测数据的有效性(不能让用户修改程序,即用户不能访问内部程序,以防用户进行非法操作)
117 0
|
编译器 C++
爱上c++的第六天(核心课程):继承和多态
学习c++的人一定知道的就是c++是面向对象设计的,而面对对象的三大特性就是封装,继承和多态,我们在刚开始学习的时候就已经学过封装了,今天我们主要来学习一下多态和继承。
56 0
|
应用服务中间件 Scala 开发者
类与对象的应用实例|学习笔记
快速学习类与对象的应用实例。
145 0
|
缓存 JavaScript 前端开发
「手摸手设计模式系列」 享元模式与资源池
享元模式 (Flyweight Pattern)运用共享技术来有效地支持大量细粒度对象的复用,以减少创建的对象的数量。 享元模式的主要思想是共享细粒度对象,也就是说如果系统中存在多个相同的对象,那么只需共享一份就可以了,不必每个都去实例化每一个对象,这样来精简内存资源,提升性能和效率。 Fly 意为苍蝇,Flyweight 指轻蝇量级,指代对象粒度很小。
「手摸手设计模式系列」 享元模式与资源池
|
设计模式 Java
最全工厂设计模式案例详解,不服来辩!
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,今天我们一起来彻底解析一下它。
最全工厂设计模式案例详解,不服来辩!