第十章 装饰者模式

news2024/11/13 11:23:49

文章目录

  • 前言
  • 一、装饰者模式定义
    • 装饰者模式 UML图
  • 二、装饰者模式解决星巴克咖啡订单
    • 完整代码
    • Drink 抽象 饮料类
    • Coffee 咖啡类继承 Drink 做一个缓冲层
    • Espresso 意大利咖啡 继承 Coffee
    • LongBlack 咖啡
    • ShortBlack 咖啡
    • 装饰者,调料
    • 牛奶
    • 巧克力
    • 豆浆
    • 咖啡店测试程序
    • ====================================================================
    • 添加 DeCaf 只因咖啡
    • 测试类
  • 三、装饰者模式在JDK应用的源码分析


前言

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


一、装饰者模式定义

在这里插入图片描述
在这里插入图片描述

装饰者模式 UML图

在这里插入图片描述

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

核心思想是装饰者和被装饰者都继承同一个父类,然后装饰者利用组合加继承递归装饰被装饰者

在这里插入图片描述

完整代码

Drink 抽象 饮料类

package tanchishell.SJMS.decorator;

public abstract class Drink {

    public String des; // 描述
    private float price = 0.0f;

    //计算费用的抽象方法
    //子类来实现
    public abstract float cost();


    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;
    }
}

Coffee 咖啡类继承 Drink 做一个缓冲层

package tanchishell.SJMS.decorator;

//咖啡类,做一个缓冲层,因为后续可能有其他的饮品加入
public class Coffee extends Drink{
    @Override
    public float cost() {
        return super.getPrice();
    }
}

Espresso 意大利咖啡 继承 Coffee

package tanchishell.SJMS.decorator;


//意大利咖啡
public class Espresso extends Coffee{
    public Espresso() {
        setDes(" 意大利咖啡 ");
        setPrice(6.0f);
    }
}

LongBlack 咖啡

package tanchishell.SJMS.decorator;


public class LongBlack extends Coffee {
    public LongBlack() {
        setDes(" LongBlack ");
        setPrice(6.0f);
    }
}

ShortBlack 咖啡

package tanchishell.SJMS.decorator;

public class ShortBlack extends Coffee {
    public ShortBlack() {
        setDes(" ShortBlack ");
        setPrice(4.0f);
    }

}

装饰者,调料

package tanchishell.SJMS.decorator;

//Decorator装饰者,继承加组合 Drink
public class Decorator extends Drink {
    //被装饰者
    private Drink obj;

    public Decorator(Drink obj) { //组合

        this.obj = obj;
    }

    @Override
    public float cost() {

        // getPrice 自己价格
        return super.getPrice() + obj.cost();
    }

    @Override
    public String getDes() {

        // obj.getDes() 输出被装饰者的信息
        return super.des + " " + super.getPrice() + " && " + obj.getDes();
    }
}

牛奶

package tanchishell.SJMS.decorator;

public class Milk extends Decorator{
    public Milk(Drink obj) {
        super(obj);
        setDes(" 牛奶 ");
        setPrice(2.0f);
    }
}

巧克力

package tanchishell.SJMS.decorator;

//具体的 Decorator, 这里就是调味品
public class Chocolate extends Decorator {
    public Chocolate(Drink obj) {
        super(obj);
        setDes(" 巧克力 ");
        setPrice(3.0f); // 调味品 的价格
    }
}

豆浆

package tanchishell.SJMS.decorator;

public class Soy extends Decorator{
    public Soy(Drink obj) {
        super(obj);
        setDes(" 豆浆 ");
        setPrice(1.5f);
    }
}

咖啡店测试程序

package tanchishell.SJMS.decorator;

public class CoffeeBar {
    public static void main(String[] args) {
        // 装饰者模式下的订单:2 份巧克力+一份牛奶的 LongBlack


        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        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());
        // 3. order 加入一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加入一份牛奶 加入一份巧克力 费用 =" + order.cost());
        System.out.println("order 加入一份牛奶 加入一份巧克力 描述 = " + order.getDes());
        // 3. order 加入一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加入一份牛奶 加入 2 份巧克力 费用 =" + order.cost());
        System.out.println("order 加入一份牛奶 加入 2 份巧克力 描述 = " + order.getDes());
    }
}

输出

费用 1=6.0
描述= LongBlack 
order 加入一份牛奶 费用 =8.0
order 加入一份牛奶 描述 =  牛奶  2.0 &&  LongBlack 
order 加入一份牛奶 加入一份巧克力 费用 =11.0
order 加入一份牛奶 加入一份巧克力 描述 =  巧克力  3.0 &&  牛奶  2.0 &&  LongBlack 
order 加入一份牛奶 加入 2 份巧克力 费用 =14.0
order 加入一份牛奶 加入 2 份巧克力 描述 =  巧克力  3.0 &&  巧克力  3.0 &&  牛奶  2.0 &&  LongBlack 

====================================================================

添加 DeCaf 只因咖啡

添加咖啡非常简单,只需要继承 Coffee 就行其他无需改变

package tanchishell.SJMS.decorator;

public class DeCaf extends Coffee{
    public DeCaf() {
        setDes(" 只因咖啡 ");
        setPrice(1.0f);
    }
}

测试类

package tanchishell.SJMS.decorator;

public class CoffeeBar {
    public static void main(String[] args) {
        // 装饰者模式下的订单:2 份巧克力+一份牛奶的 LongBlack


        // 1. 点一份 LongBlack
        Drink order = new LongBlack();
        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());
        // 3. order 加入一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加入一份牛奶 加入一份巧克力 费用 =" + order.cost());
        System.out.println("order 加入一份牛奶 加入一份巧克力 描述 = " + order.getDes());
        // 3. order 加入一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加入一份牛奶 加入 2 份巧克力 费用 =" + order.cost());
        System.out.println("order 加入一份牛奶 加入 2 份巧克力 描述 = " + order.getDes());


        System.out.println("=========新建订单 只因咖啡==================");
        Drink order2 = new DeCaf();
        System.out.println("order2 只因咖啡 费用 =" + order2.cost());
        System.out.println("order2 只因咖啡 描述 = " + order2.getDes());
        order2 = new Milk(order2);
        System.out.println("order2 只因咖啡 加入一份牛奶 费用 =" + order2.cost());
        System.out.println("order2 只因咖啡 加入一份牛奶 描述 = " + order2.getDes());
    }
}

输出

费用 1=6.0
描述= LongBlack 
order 加入一份牛奶 费用 =8.0
order 加入一份牛奶 描述 =  牛奶  2.0 &&  LongBlack 
order 加入一份牛奶 加入一份巧克力 费用 =11.0
order 加入一份牛奶 加入一份巧克力 描述 =  巧克力  3.0 &&  牛奶  2.0 &&  LongBlack 
order 加入一份牛奶 加入 2 份巧克力 费用 =14.0
order 加入一份牛奶 加入 2 份巧克力 描述 =  巧克力  3.0 &&  巧克力  3.0 &&  牛奶  2.0 &&  LongBlack 
=========新建订单 只因咖啡==================
order2 只因咖啡 费用 =1.0
order2 只因咖啡 描述 =  只因咖啡 
order2 只因咖啡 加入一份牛奶 费用 =3.0
order2 只因咖啡 加入一份牛奶 描述 =  牛奶  2.0 &&  只因咖啡 

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

在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

01-yolo算法

要点: 归纳 YOLOv5 github 1 YOLO v1 1) 将一幅图像分成SxS个网格(grid cell),如果某个object的中心 落在这个网格中,则这个网格就负责预测这个object。 2)每个网格要预测B个bounding box,每个bounding box 除了要预测位置之…

TortoiseSVN使用-合并分支代码

文章目录 3.4.12 合并分支代码TortoiseSVN有2种合并方式演示场景1:(合并一个版本范围 Merge a range of revisions)演示场景2:(合并两个不同的树 Merge two different trees),不设置主分支版本演…

初窥Edubuntu 23.04:装有教育软件的Ubuntu桌面

导读4月20日,Edubuntu将作为Ubuntu官方口味卷土重来,作为即将发布的Ubuntu 23.04(Lunar Lobster)的一部分,所以我认为让你们先看看这个重制版中包含的内容是个好主意。 Edubuntu以前被称为Ubuntu教育版,最…

Anaconda安装及tensorflow安装

1.下载Anaconda安装包,并安装好 官网下载网址:https://www.anaconda.com/download/ 清华映像站: https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 注意:注意安装anaconda时一定要把环境变量加入windows环境中。若没有…

C语言---函数介绍详解

生活的全部意义在于无穷地探索尚未知道的东西,在于不断地增加更多的知识——左拉 文章目录 前言函数模块化程序设计方法函数的定义函数的分类函数定义角度库函数自定义函数 函数形式角度无参函数有参函数 函数兼有其他语言中的函数和过程两种功能的角度有返回值函数无返回值函…

ENVI 国产高分2号(GF-2)卫星数据辐射定标 大气校正 影像融合

1.数据 高分2号卫星数据,包含: MSS-1\2多光谱数据,4m分辨率; Pan-1\2全色波段数据,0.8m分辨率。 2.处理软件 ENVI5.3 国产插件下载地址:ENVI App Store (geoscene.cn) 首先下载插件文件; …

Spring的事务传播行为

事务传播行为 多个声明的事务的方法在相互调用的时候,这个是事务应该如何去传递。 比如说methodA()调用methodB(), 那么这两个方法都显示了开启了事务,那么methodB()是开启一个新的事务还是继续在methodA()这个事务里面去执行就取决于所谓的事务传播的…

多兴趣推荐召回模型:ComiRec

前言 多兴趣向量召回系列: 通过Youtube DNN推荐模型来理解推荐流程 多兴趣召回模型:MIND 推荐系统可以表达为序列推荐问题的形式,序列推荐任务是通过用户的历史行为来预测用户下一个感兴趣的item,这也与真实场景的推荐场景是符…

Linux 通过Chrony实现NTP

Linux实现NTP服务器时间同步,可以通过ntp服务实现,也可以通过chrony服务实现 两者区别主要有 Chrony运行于UDP的323端口,NTP运行于UDP的123端口 Chrony相比于NTP可以更快同步,能够最大同步的减少时间和频率的误差 Chrony能够更好…

linux安装harbor ,搭建镜像私服

linux安装harbor ,搭建镜像私服 前提 环境中要有 docker 和 docker-compose 2、下载 harbor 的 .tgz 安装包 官网地址: Releases goharbor/harbor GitHub 第一个是离线安装包,第二个是在线安装包;带asc后缀的文件就是校验…

ROS学习第三十二节——xacro构建激光雷达小车

https://download.csdn.net/download/qq_45685327/87718396 在前面小车底盘基础之上&#xff0c;添加摄像头和雷达传感器。 0.底盘实现 deamo02_base.xacro <!--使用 xacro 优化 URDF 版的小车底盘实现&#xff1a;实现思路:1.将一些常量、变量封装为 xacro:property比如…

【Spring】Spring AOP

目录 一、Spring AOP简介1.什么是AOP2.AOP术语 二、AspectJ开发1.基于XML的声明式AspectJ1.1 配置切面1.2 配置切入点1.3 配置通知 2.基于注解的声明式AspectJ 一、Spring AOP简介 1.什么是AOP AOP的全称是Aspect-Oriented Programming&#xff0c;即面向切面编程&#xff08;…

一种引入过渡阶段和高斯变异的改进算术优化算法(TGAOA)-附代码

一种引入过渡阶段和高斯变异的改进算术优化算法(TGAOA) 文章目录 一种引入过渡阶段和高斯变异的改进算术优化算法(TGAOA)1.算术优化算法2. 改进算术优化算法2.1 重构数学加速优化器 MOA2.2 新策略的引入2.3 具有一致性的高斯变异策略2.4具有一致性的高斯变异策略 3.实验结果4.参…

YOLOv8 应用轻量级通用上采样算子CARAFE

特征上采样是现代卷积神经网络架构中的关键操作,例如特征金字塔。其设计对于密集预测任务,如目标检测和语义/实例分割至关重要。在本研究中,我们提出了一种称为内容感知特征重组(CARAFE)的通用、轻量级且高效的操作符,以实现这一目标。CARAFE具有以下几个优点:(1)大的…

模型评估与选择

一、问题 在现实任务中&#xff0c;我们往往有多种学习算沾了供选择&#xff0c;甚至对同 -个学习算法&#xff0c;当使用不同的参数配置时也会产生不 同的模型 . 那么&#xff0c;我们该选用 哪一个学习算法、使用哪一种参数配置呢? 理想的解决方案当然是对候选模型的泛化误…

Java线程详解

线程是CPU调度和分配的基本单位&#xff0c;是操作系统可以识别的最小执行和调度单位&#xff0c;每个线程都有自己特定的独立的内存区域&#xff0c;当然也与其他线程共享堆内存&#xff0c;文件队列以及其他内核资源&#xff0c;Java虚拟机允许一个应用拥有多个线程并发工作。…

AI绘画——Lora模型 小人书·连环画 xiaorenshu

目录 小人书连环画 使用说明&#xff1a; Instructions for v1.5: Instructions for v1.0: 下载地址 模型演示&#xff08;多图预警&#xff09; Night Sky YOZORA Model 模型 Lora模型xiaorenshu pastel-mix模型pastel-waifu-diffusion.vae模型Lora模型xiaorenshu 小人书…

JavaSE05|数组的定义与使用

文章目录 JavaSE05|**数组的定义与使用**1.数据基本概念**2.** **数组是引用类型****3.** **数组的应用场景** JavaSE05|数组的定义与使用 1.数据基本概念 定义&#xff1a;可以看成是相同类型元素的一个集合 1.1数组初始化 动态初始化&#xff1a;在创建数组时&#xff0c…

使用 Kubectl Patch 命令更新资源

Kubectl patch 命令允许用户对运行在 Kubernetes 集群中的资源进行局部更新。相较于我们经常使用的 kubectl apply 命令&#xff0c;kubectl patch 命令在更新时无需提供完整的资源文件&#xff0c;只需要提供要更新的内容即可。 Kubectl patch 支持以下 3 种 patch 类型&…

ROS学习第三十三节——Arbotix使用

https://download.csdn.net/download/qq_45685327/87718484 1.介绍 通过 URDF 结合 rviz 可以创建并显示机器人模型&#xff0c;不过&#xff0c;当前实现的只是静态模型&#xff0c;如何控制模型的运动呢&#xff1f;在此&#xff0c;可以调用 Arbotix 实现此功能。 Arboti…