• 【设计模式】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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    ②、定义单体类

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

    package com.lyd.demo.drink;
    /**
     * @Author: lyd
     * @Description: 奶茶类
     * @Date: 2022-08-29
     */
    public class MilkTea extends Drink {
        @Override
        public float cost() {
            return super.getPrice();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ③、定义具体奶茶

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

    package com.lyd.demo.drink;
    /**
     * @Author: lyd
     * @Description: 红豆奶茶
     * @Date: 2022-08-29
     */
    public class RedBeanMilkTea extends MilkTea {
        public RedBeanMilkTea() {
            setDescribe(" 红豆奶茶 ");
            setPrice(7.0f);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ④、定义装饰类

    总体装饰者,继承饮料类

    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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    ⑤、定义具体装饰者

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

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ⑥、测试实例

    买一杯 红豆奶茶 + 牛奶 + 布丁。
    通过父类实例化具体的奶茶子类,调用其计算总价方法;要是需要加料,只要把奶茶实例放到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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    运行结果:
    在这里插入图片描述

    好文推荐

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

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

  • 相关阅读:
    canal-1.1.5实时同步MySQL数据到Elasticsearch
    【Linux】云服务器的购买与Linux远程连接
    Python的10个编程技巧,你不一定都知道
    HTTP协议
    ViT结构详解(pytorch代码)
    seq2seq与引入注意力机制的seq2seq
    LeetCode_栈_中等_150. 逆波兰表达式求值
    【刷题笔记】动态规划
    GIS数据获取:土地利用与土壤属性、DEM、水体水系数据
    FANUC机器人零点复归的报警原因分析和零点标定相关步骤
  • 原文地址:https://blog.csdn.net/qq_43843951/article/details/126594789