【设计模式】Java设计模式-装饰者模式

Java设计模式 – 装饰者模式

😄 不断学习才是王道
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆原创作品,更多关注我CSDN: 一个有梦有戏的人
👊准备将博客园、CSDN一起记录分享自己的学习心得!!!
🌝分享学习心得,欢迎指正,大家一起学习成长!

【设计模式】Java设计模式-装饰者模式

简介

装饰者模式是一种结构型模型,是动态的给对象增加职责,对于新增功能来说要比通过子类方式更加的灵活。他允许对一个对象进行添加新的功能,但不能改变结构。

装饰者模式实例

德德奶茶店里有许多种奶茶,奶茶还能根据自己的喜欢添加额外的料。加入奶茶有很多种,料也有很多,要求既能够在扩展奶茶种类的时候,改动方便,不能改变结构。使用面向对象的方式计算不同种类奶茶的费用。用户可以只买不加料,也可以买奶茶再根据自己的喜好加料。

既想实现需求,又不能让类太繁重,又要做到高扩展,改动方便。于是就使用了装饰者模式,简单说一下如何使用装饰者首先需要一个抽象类,里面除了价格等属性,还需要有个能够让子类实现的抽象方法来计算费用。具体的奶茶再来继承这个抽象类,实现其方法并设置初始值。还需要定义总体装饰者,他是继承了抽象类,采用组合的方式,计算总价格,其他真正地装饰者也就是调料,他们再去继承这个总体装饰者。使用的使用只要实例化父类,对象为具体的奶茶类型,在加料的时候,只需要把这杯奶茶送到装饰者上,去让装饰者装饰,最后返回还是这个父类。
具体的类图如下

【设计模式】Java设计模式-装饰者模式

接下来一步一步编写代码来实现买一杯 红豆奶茶 + 牛奶 + 布丁

①、抽象类

定义饮料-抽象类,包含描述和费用两个属性,还有个抽象方法-计算价格,提供给子类去实现。

package com.lyd.demo.drink;
/**
 * @Author: lyd
 * @Description: 饮料-抽象类
 * @Date: 2022-08-29
 */
public abstract class Drink {
    private String describe; // 描述
    private float price = 0.0f;
    public String getDescribe() {
        return describe;
    }
    public void setDescribe(String describe) {
        this.describe = describe;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    // 计算费用 - 抽象 - 子类实现
    public abstract float cost();
}

②、定义单体类

定义奶茶类,只需要继承饮料类,并且获取父类的价格。

package com.lyd.demo.drink;
/**
 * @Author: lyd
 * @Description: 奶茶类
 * @Date: 2022-08-29
 */
public class MilkTea extends Drink {
    @Override
    public float cost() {
        return super.getPrice();
    }
}

③、定义具体奶茶

红豆奶茶和珍珠奶茶的代码相似,这里只粘贴红豆奶代码。具体奶茶,要设置描述和单价。

package com.lyd.demo.drink;
/**
 * @Author: lyd
 * @Description: 红豆奶茶
 * @Date: 2022-08-29
 */
public class RedBeanMilkTea extends MilkTea {
    public RedBeanMilkTea() {
        setDescribe(" 红豆奶茶 ");
        setPrice(7.0f);
    }
}

④、定义装饰类

总体装饰者,继承饮料类

package com.lyd.demo.decorator;
import com.lyd.demo.drink.Drink;
/**
 * @Author: lyd
 * @Description: 装饰者
 * @Date: 2022-08-29
 */
public class Decorator extends Drink {
    Drink drink;
    public Decorator(Drink drink) { // 组合
        this.drink = drink;
    }
    @Override
    public float cost() {
        // 计算价格综合
        return super.getPrice() + drink.cost();
    }
    @Override
    public String getDescribe() {
        return drink.getDescribe() + " + " + super.getDescribe() + " " + super.getPrice();
    }
}

⑤、定义具体装饰者

具体装饰者就是要添加的料,这里只粘贴单个代码示例,其他相似。

package com.lyd.demo.decorator;
import com.lyd.demo.drink.Drink;
/**
 * @Author: lyd
 * @Description: 装饰器 - 牛奶
 * @Date: 2022-08-29
 */
public class Milk extends Decorator {
    public Milk(Drink drink) {
        super(drink);
        setDescribe(" 牛奶 ");
        setPrice(3.0f);
    }
}

⑥、测试实例

买一杯 红豆奶茶 + 牛奶 + 布丁。
通过父类实例化具体的奶茶子类,调用其计算总价方法;要是需要加料,只要把奶茶实例放到new调料实例中,让装饰者去装饰这个类,最后返回也是饮料类。通过层层套入装饰的方式就实现了装饰者模式。在此,如果是买第二杯奶茶,只需要在new一个对应奶茶的实例。如果还有额外的品种奶茶需要添加,只要继续添加xx奶茶类,不会改变结构,或者是需要添加调料,也是如此操作,让其多个具体的装饰者。

package com.lyd.demo.test;
import com.lyd.demo.decorator.Milk;
import com.lyd.demo.decorator.Pudding;
import com.lyd.demo.drink.Drink;
import com.lyd.demo.drink.PearlMilkTea;
/**
 * @Author: lyd
 * @Description: 测试类
 * @Date: 2022-08-29
 */
public class DecorateTest {
    public static void main(String[] args) {
        // 买一杯 红豆奶茶 + 牛奶 + 布丁
        // 实例化为父类对象,红豆奶茶
        Drink pearlMilkTea = new PearlMilkTea();
        // 先观察红豆奶茶的输出
        System.out.println("您购买了: " + pearlMilkTea.getDescribe());
        System.out.println("您购买的费用: " + pearlMilkTea.cost());
        // 添加牛奶之后
        System.out.println("添加牛奶之后");
        pearlMilkTea = new Milk(pearlMilkTea);
        System.out.println("您购买了: " + pearlMilkTea.getDescribe());
        System.out.println("您购买的费用: " + pearlMilkTea.cost());
        // 再添加布丁之后
        System.out.println("再添加布丁之后");
        pearlMilkTea = new Pudding(pearlMilkTea);
        System.out.println("您购买了: " + pearlMilkTea.getDescribe());
        System.out.println("您购买的费用: " + pearlMilkTea.cost());
    }
}

运行结果:

【设计模式】Java设计模式-装饰者模式

好文推荐

👍创作不易,可能有些语言不是很通畅,如有错误请指正,感谢观看!记得一键三连哦!👍

看过百遍,还不如动手一遍,动手敲敲代码有助于理解,设计模式不是很容易就理解,需要动手尝试,这样不仅能够学会设计模式,更能够更好的理解java面向对象。

Original: https://www.cnblogs.com/lyd-code/p/16684312.html
Author: 怒放吧德德
Title: 【设计模式】Java设计模式-装饰者模式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/619739/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • SpringCloudAlibaba项目之OpenFeign远程调用

    SpringCloudAlibaba随笔目录 一、SpringCloudAlibaba项目之父工程搭建 二、 SpringCloudAlibaba项目之Nacos搭建及服务注册 三…

    Java 2023年6月5日
    082
  • ASP.NET MVC 自定义处理JSON ActionResult类

    1、统一JSON格式处理方式,同时指定ContentType类型,解决低版本浏览器获取json时ContentType为application/json提示下载的问题. publi…

    Java 2023年6月5日
    069
  • java基础

    深入循环结构 for(循环条件1) { //循环操作1 for(循环条件2) { //循环操作2 } } 多层循环: 外层循环变量变化一次,内层循环变量要变化一轮。 一、循环打印输…

    Java 2023年6月13日
    072
  • 1.1 File类的简单使用

    File类的使用 在学习File类之前,我们需要知道一个知识点的概念、有什么用、需要掌握的东西以及学完后我能做出什么东西出来等。 所以后面的章节也会以这几个点来作为主要的讲解。 1…

    Java 2023年6月13日
    089
  • Android 快速点击的处理

    为了对付拥有麒麟臂的测试人员或者用户对我们的按钮等控件展开惨无人道的快速啄击。厮以为可以用如下方法: 1 setEnabled 大法;在用户点击发生后调用setEnable(fal…

    Java 2023年6月9日
    061
  • 【Spring源码分析】Bean加载流程概览(转)

    转载自:https://www.cnblogs.com/xrq730/p/6285358.html 代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入【Spring源码分析】这个板…

    Java 2023年5月29日
    083
  • 【转】Java之WeakReference与SoftReference使用讲解

    Java 2 平台引入了 java.lang.ref 包,其中包括的类可以让您引用对象,而不将它们留在内存中。这些类还提供了与垃圾收集器(garbage collector)之间有…

    Java 2023年5月29日
    076
  • bat脚本的写法

    当你每次都要输入相同的命令时,可以把这么多命令存为一个批处理,从此以后,只要运行这个批处理,就相当于打了几行、几十行命令。下面以Nginx服务的停止脚本为例写一个bat批处理文件:…

    Java 2023年6月16日
    064
  • 力扣|Q997找法官FindTheTownJudge

    Q997FindTheTownJudge 简介 小镇里有 n 个人,按从 1 到 n 的顺序编号。传言称,这些人中有一个暗地里是小镇法官。 如果小镇法官真的存在,那么: 小镇法官不…

    Java 2023年6月8日
    0113
  • SpringBoot-异常处理

    在SpringBoot中,无论是请求不存在的路径、@Valid校验,还是业务代码(Controller、Service、Dao)抛出异常,SpringBoot对错误的默认处理机制是…

    Java 2023年6月6日
    069
  • 「SpringBoot」如何优雅地启动管理SpringBoot项目

    本文主要讲述一下如何优雅地管理SpringBoot项目。 背景 课堂上,当小明形如流水地回答完沐芳老师提出来的问题时,却被至今没有对象的胖虎无情嘲讽了? 沐芳老师:小明,你平时是如…

    Java 2023年6月13日
    097
  • Spring Cloud认知学习(四):熔断器Hystrix的使用

    Hystrix 服务熔断和服务降级 简单使用示例: 部署在服务提供者 部署在服务消费者 整合feign 1.修改Feign代码 2.修改消费者 3.测试: Hystrix Dash…

    Java 2023年5月30日
    088
  • Response 重写设置返回值

    import cn.dolphin.core.exception.IoRuntimeException; import cn.dolphin.core.result.ApiResu…

    Java 2023年6月9日
    076
  • 设计模式之代理模式(Proxy Pattern)

    1.1、介绍 代理模式(Proxy Pattern)给某一个对象提供一个代理,并由代理对象控制原对象的引用。代理对象在客户端和目标对象之间起到中介作用 。 代理模式是常用的结构型设…

    Java 2023年6月7日
    077
  • 黑喵桌面音乐播放器汉化版

    安装方法:解压CharaColle,运行Regpatch。exe 注册游戏(XP 系统需要装.net framework 2.0)即可启动游戏。启动比较慢,请大家耐心下 使用说明:…

    Java 2023年5月29日
    067
  • 保姆教程系列一、Linux搭建Nacos

    前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 简介: Nacos是阿里巴巴开源的一款支持服务注册与发现,配置管理以及微服务管理的组件。用来取代以前常用的注册中心…

    Java 2023年6月5日
    097
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球