【设计模式】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)

大家都在看

  • 域名+端口号 访问minio服务问题

    业务上需要用到分布式文件服务,选择了minio作为文件服务的组件,搭建好服务后使用IP+端口号(http://xx.xx.xx.xx:9001)的形式访问在所有环境下都没有问题。上…

    Java 2023年6月13日
    084
  • Fizz网关入门教程-快速聚合多接口

    背景介绍 先看一张图,页面一共调用了20多个后端接口,页面出现了明显的卡顿,而且每6个请求一组,只有前一组返回后才执行下一组。看到请求是pending状态,很容易以为是后端接口的问…

    Java 2023年6月9日
    098
  • 终于上传了一篇文章

    拖了好久的第一批文章今天终于写完上传了,以后会有陆陆续续的文章上传,最近几篇都是以提高开发效率和系统移植解决方案的文章,有兴趣的朋友请关注后续文章,有全新开发的项目的朋友可以联系我…

    Java 2023年6月8日
    089
  • 多线程编程总结:三、Task的使用和意义

    Task 创建每个线程需要占用1MB的虚拟内存,并且线程过多会导致CPU耗费大量时间在切换不同线程上。所以在之前我们会使用线程池来自动分配线程。 在.Net Framwork 4,…

    Java 2023年5月30日
    082
  • 设计模式

    设计模式 工厂模式 public class Test { public static void main(String[] args) { Computer c1 =Comput…

    Java 2023年6月9日
    084
  • kafka从入门到了解

    kafka从入门到了解 一、什么是kafka Apache Kafka是Apache软件基金会的开源的流处理平台,该平台提供了消息的订阅与发布的消息队列,一般用作系统间解耦、异步通…

    Java 2023年6月13日
    0103
  • msf攻击android

    msf攻击android [1] 1.msf生成android apk文件 msfvenom -p android/meterpreter/reverse_tcp lhost= l…

    Java 2023年6月14日
    097
  • 极客时间《Flink 核心技术与实战》课程学习

    参考文件:https://gitee.com/zhanglibing1990/geektime-Flink kubernetes(k8s) Flink高可用 Watermark 项…

    Java 2023年6月7日
    0114
  • 为什么说Java8的Stream并行流底层使用了Fork/Join框架

    先说结论 Stream 是支持串行和并行执行这两种方式的 调用parallel方法即可 Stream.of(1, 2, 3, 4, 5).parallel() 先写一个Java8S…

    Java 2023年5月29日
    081
  • 各种java面试题目

    地址:https://www.cnblogs.com/crazymakercircle/p/14365820.html 月薪过5万 面试题 总目录 搞定下面这些面试题,2021春招…

    Java 2023年5月29日
    083
  • MySQL学习-eclipse导入jar包

    导包先有包 !!!一定要下载和自己MySQL版本一样的jar包!!! !!!一定要下载和自己MySQL版本一样的jar包!!! !!!一定要下载和自己MySQL版本一样的jar包!…

    Java 2023年6月9日
    080
  • SpringBoot框架学习教程,初学者用7天学完springboot直接去面试了

    如果你跟我一样,刚巧也是springboot小白,正要学springboot,建议看完下一段话: Spring Boot 是由 Pivotal 团队提供用来简化 Spring 的搭…

    Java 2023年6月7日
    071
  • 52类110个主流的Java框架

    上次写了一篇讲 Java 工具的文章。 有读者看完在微信问我,能不能总结一个更全的 Java 主流框架? 我本以为整理这个没多难,后来一边整理一边感觉越来越多…&#82…

    Java 2023年6月7日
    074
  • Spring知识点总结5 反射与代理

    反射机制允许程序在执行期借助API取得任何类的内部信息,并能直接操作任意对象的内部属性方法 反射 java反射机制提供的功能 在运行期间判断任意一个对象所属的类 在运行期间构造任意…

    Java 2023年6月6日
    075
  • Java集合框架概述:Collection(List, Set, Queue)和Map

    http://sparkandshine.net/java-collections-framework-overview-collection-list-set-queue-map…

    Java 2023年5月29日
    089
  • 中国DevOps平台市场,华为云再次位居领导者位置

    摘要:华为云软件开发生产线DevCloud在市场份额和发展战略两大维度均排名第一,再次位居领导者位置。 9月21日 ,国际权威分析师机构IDC发布《IDC MarketScape:…

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