装饰者设计模式解读

问题引进

星巴克咖啡订单项目(咖啡馆):
1) 咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)
2) 调料:Milk、Soy(豆浆)、Chocolate
3) 要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
4) 使用 OO 的来计算不同种类咖啡的费用: 客户可以点单品咖啡,也可以单品咖啡+调料组合。

方案 1-解决星巴克咖啡订单项目 

 方案 1-解决星巴克咖啡订单问题分析

1) Drink 是一个抽象类,表示饮料
2) des 就是对咖啡的描述, 比如咖啡的名字
3) cost() 方法就是计算费用,Drink 类中做成一个抽象方法.
4) Decaf 就是单品咖啡, 继承 Drink, 并实现 cost
5) Espress && Milk 就是单品咖啡+调料, 这个组合很多

问题:这样设计,会有很多类,当我们增加一个单品咖啡,或者一个新的调料,类的数量就会倍增,就会出现类爆炸

方案 2-解决星巴克咖啡订单(好点) 

前面分析到方案 1 因为咖啡单品+调料组合会造成类的倍增,因此可以做改进,将调料内置到 Drink 类,这样就不会造成类数量过多。从而提高项目的维护性(如图)

方案 2-解决星巴克咖啡订单问题分析 

1) 方案 2 可以控制类的数量,不至于造成很多的类
2) 在增加或者删除调料种类时,代码的维护量很大
3) 考虑到用户可以添加多份 调料时,可以将 hasMilk 返回一个对应 int
4) 考虑使用 装饰者 模式

装饰者模式概述

装饰者模式定义

1) 装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
2) 这里提到的动态的将新功能附加到对象和 ocp 原则,在后面的应用实例上会以代码的形式体现,请大家注意体会。

装饰者模式原理

1) 装饰者模式就像打包一个快递
主体:比如:陶瓷、衣服 (Component) // 被装饰者
包装:比如:报纸填充、塑料泡沫、纸板、木板(Decorator)

2) Component 主体:比如类似前面的 Drink

3) ConcreteComponent 和 Decorator
ConcreteComponent:具体的主体,
比如前面的各个单品咖啡

4) Decorator: 装饰者,比如各调料.
在如图的 Component 与 ConcreteComponent 之间,如果 ConcreteComponent 类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象层一个类。

装饰者模式解决星巴克咖啡订单 

public abstract class Drink {
    public String des;
    private  float price=0.0f;

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
    //计算费用的抽象方法
    //子类来实现
    public abstract float cost();
}
public class Coffee extends  Drink{

    @Override
    public float cost() {
        return super.getPrice();
    }
}
public class Espresso extends  Coffee  {

    public Espresso() {
        setDes(" 意大利咖啡 ");
        setPrice(5.0f);
    }
}
public class Decorator extends Drink {

    private Drink obj;

    public Decorator(Drink obj) { //组合
        this.obj = obj;
    }

    @Override
    public float cost() {
        return super.getPrice()+obj.cost();
    }
}
public class Milk extends Decorator{

    public Milk(Drink obj) {
        super(obj);
        setDes(" 牛奶 ");
        setPrice(2.0f);
    }
}
public class client {
    public static void main(String[] args) {
        Drink order = new Espresso();
        System.out.println("费用 1=" + order.cost());
        System.out.println("描述=" + order.getDes());
        // 2. order 加入一份牛奶
        order = new Milk(order);
        System.out.println("order 加入一份牛奶 费用 =" + order.cost());
        System.out.println("order 加入一份牛奶 描述 = " + order.getDes());
        // 2. order 加入一份牛奶
        order = new Milk(order);
        System.out.println("order 加入2份牛奶 费用 =" + order.cost());
        System.out.println("order 加入2份牛奶 描述 = " + order.getDes());
    }
}

费用=5.0
描述= 意大利咖啡 
order 加入一份牛奶 费用 =7.0
order 加入一份牛奶 描述 =  牛奶 
order 加入2份牛奶 费用 =9.0
order 加入2份牛奶 描述 =  牛奶 

Process finished with exit code 0

装饰者模式在 JDK 应用的源码分析 

/说明
//1. InputStream 是抽象类, 类似我们前面讲的 Drink
//2. FileInputStream 是 InputStream 子类,类似我们前面的 DeCaf, LongBlack
//3. FilterInputStream 是 InputStream 子类:类似我们前面 的 Decorator 修饰者
//4. DataInputStream 是 FilterInputStream 子类,具体的修饰者,类似前面的 Milk, Soy 等
//5. FilterInputStream 类 有 protected volatile InputStream in; 即含被装饰者
//6. 分析得出在 jdk 的 io 体系中,就是使用装饰者模式
DataInputStream dis = new DataInputStream(new FileInputStream("d:\\abc.txt"));
System.out.println(dis.read());
dis.close();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/21757.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

接口测试全流程扫盲,让我看看有哪些漏网之鱼

目录 扫盲内容: 1.什么是接口? 2.接口都有哪些类型? 3.接口的本质及其工作原理是什么? 4.什么是接口测试? 5.问什么要做接口测试? 6.怎样做接口测试? 7.接口测测试点是什么?…

一些云原生开源安全工具介绍

本博客地址:https://security.blog.csdn.net/article/details/130789465 一、Kubernetes安全监测工具kube-bench kube-bench是一个用Golang开发的、由Aqua Security发布的自动化Kubernetes基准测试工具,它运行CIS Kubernetes基准中的测试项目。这些测试…

MySQL高级篇第一天

目录 一、索引 二、索引结构 三、索引分类 四、索引语法 五、索引设计原则 六、视图 七、存储过程与概述 八、触发器 九、总结 一、索引 (一)索引概述 索引是一种能够帮组Mysql高效的从磁盘上查询数据的一种数据结构,这些数据结构以某…

用WaveNet预测(Adapted Google WaveNet-Time Series Forecasting)

目录 剧情简介: 数据来源 加载数据 分割数据和可视化 时间序列的多元波网模型:实现(多步预测) 创建模型 创建数据集 数据准备 1- Training dataset preparation 2- Validation dataset preparation Train the Model with TPU: 使用经过训练的适应Google WaveNet预测…

YOLO NAS note 1

Git Hub: https://github.com/Deci-AI/super-gradients Yolo-Nas 的代码比YOLO v8 还恐怖。之前的YOLO数据可以通过: coco_detection_yolo_format_train, 和 coco_detection_yolo_format_val 自动转。 这里写目录标题 Train数据获取数据增强训练criteri…

ChatGPT 提问,软件杂项部分

堆内存与栈内存一般分别 有多少 ChatGPT 堆内存和栈内存的大小取决于操作系统和编译器的限制以及程序的运行环境。以下是一些常见的默认大小范围,但请注意这些值可以因环境而异: 栈内存大小: Windows平台:默认情况下&#xff…

CNN实现手写数字识别(Pytorch)

CNN结构 CNN(卷积神经网络)主要包括卷积层、池化层和全连接层。输入数据经过多个卷积层和池化层提取图片信息后,最后经过若干个全连接层获得最终的输出。 CNN的实现主要包括以下步骤: 数据加载与预处理模型搭建定义损失函数、优…

应用现代化中的弹性伸缩

作者:马伟,青云科技容器顾问,云原生爱好者,目前专注于云原生技术,云原生领域技术栈涉及 Kubernetes、KubeSphere、KubeKey 等。 2019 年,我在给很多企业部署虚拟化,介绍虚拟网络和虚拟存储。 2…

微服务架构初探

大家好,我是易安!我们今天来谈一谈微服务架构的前世今生。 我们先来看看维基百科是如何定义微服务的。微服务的概念最早是在2014年由Martin Fowler和James Lewis共同提出,他们定义了微服务是由单一应用程序构成的小服务,拥有自己的…

建立在Safe生态的—GameFi SocialFi双赛道项目No.1头号玩家

最近大家关注的重点在BRC-20和MEME项目,人们似乎更在意短期的投机回报。而在这之外,一个web3的游戏——No.1头号玩家却得到了大量的玩家支持。 据了解,No.1是一个GameFi & SocialFi的双赛道web3游戏,中文名称为头号玩家。它是…

光纤衰减器作用及使用说明

在光纤通信中,光信号的强度过大或过小都会对信号的传输和接收产生不良的影响,因此光衰减器在光通信系统中起到了重要的作用。那什么是光衰减器呢?它又有什么作用呢?下面跟着小易一起来了解一下吧! 一、什么是光纤衰减…

HUSTOJ中添加初赛练习系统

文章目录 0. 基于hustoj二开的初赛练习系统,QQ4705852261. 主界面2. 练习界面3. 模拟考试界面4. 查看试卷回放5. 后台操作界面6. 后台试题分类-列表7.后台试题-列表8. 后台试题-添加9. 后台试卷结构-设置 0. 基于hustoj二开的初赛练习系统,QQ470585226 …

[笔记]渗透测试工具Burpsuit《一》Burpsuit介绍

文章目录 前言一、安装配置1.1 环境1.2 安装过程1.3 科技过程 二、常用功能2.1 Manual penetration testing features2.2 Advanced/custom automated attacks2.3 Automated scanning for vulnerabilities2.4 Productivity tools2.5 Extensions 三、拓展功能 前言 Burp Suite(b…

一、预约挂号微服务模块搭建

文章目录 一、预约挂号微服务模块搭建1、项目模块构建2、sql资源3、构建父工程(yygh-parent)3.1、添加配置pom.xml 4、搭建common父模块4.1、搭建common4.2、修改配置pom.xml 5、搭建common-util模块5.1、搭建common-util5.2、修改配置pom.xml5.3、添加公…

ELK的安装部署与使用

ELK的安装与使用 安装部署 部署环境:Elasticsearch-7.17.3 Logstash-7.17.3 Kibana-7.17.3 一、安装部署Elasticsearch 解压目录,进入conf目录下编辑elasticsearch.yml文件,输入以下内容并保存 network.host: 127.0.0.1 http.port: 9200…

计算机网络实验(ensp)-实验10:三层交换机实现VLAN间路由

目录 实验报告: 实验操作 1.建立网络拓扑图并开启设备 2.配置主机 1.打开PC机 配置IP地址和子网掩码 2.配置完成后点击“应用”退出 3.重复步骤1和2配置每台PC 3.配置交换机VLAN 1.点开交换机 2.输入命名:sys 从用户视图切换到系统视图…

Jenkins版本升级

Jenkins版本过低的时候,一些插件无法升级,会引发一系列错误,这个时候我们就要升级版本了 一、下载更新包 第一种方式:Jenkins页面下载最新包 第二种官网上下载war包(Jenkins官网) 二、打开服务器搜索jenkins.war路径 1、如果Jenk…

SQL Backup Master 6.3.6 Crack

SQL Backup Master 能够为用户将 SQL Server 数据库备份到一些简单的云存储服务中,例如 Dropbox、OneDrive、Amazon S3、Microsoft Azure、box,最后是 Google Drive。它能够将数据库备份到用户和开发者的FTP服务器上,甚至本地机器甚至网络服务…

这几款实用的电脑软件推荐给你

软件一:TeamViewer TeamViewer是一款跨平台的远程控制软件,它可以帮助用户远程访问和控制其他计算机、服务器、移动设备等,并且支持文件传输、会议功能等。 TeamViewer的主要功能包括: 远程控制:支持远程访问和控制…

HANTS时间序列滤波算法的MATLAB实现

本文介绍在MATLAB中,实现基于HANTS算法(时间序列谐波分析法)的长时间序列数据去噪、重建、填补的详细方法。 HANTS(Harmonic Analysis of Time Series)是一种用于时间序列分析和插值的算法。它基于谐波分析原理&#x…