深入浅出设计模式 - 装饰者模式

这篇具有很好参考价值的文章主要介绍了深入浅出设计模式 - 装饰者模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

深入浅出设计模式 - 装饰者模式

1、什么是装饰者模式

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许你向一个现有的对象添加新的功能,同时又不改变其结构。装饰者模式基于组合而非继承的原则,它动态地将责任附加到对象上。

装饰者模式涉及到四个角色:抽象组件、具体组件、抽象装饰者和具体装饰者。其中,抽象组件定义了组件的基本功能,具体组件实现了组件的基本功能,抽象装饰者定义了装饰者的基本功能,具体装饰者实现了装饰者的基本功能,并且可以添加额外的功能。

装饰者模式的优点是可以动态地添加或删除对象的功能,而不需要修改现有的代码。它还可以避免使用子类来扩展对象的功能,从而减少类的数量。缺点是装饰者模式会增加许多小对象,从而增加系统的复杂性。

2、装饰者模式的优缺点

装饰者模式的优点包括:

  1. 可以动态地添加或删除对象的功能,而不需要修改现有的代码。

  2. 可以避免使用子类来扩展对象的功能,从而减少类的数量。

  3. 可以将多个装饰者组合起来,实现更复杂的功能。

装饰者模式的缺点包括:

  1. 装饰者模式会增加许多小对象,从而增加系统的复杂性。

  2. 装饰者模式可能会导致设计变得过于抽象,从而难以理解和维护。

  3. 装饰者模式可能会影响程序的性能,因为每个装饰者都会增加额外的处理时间。

3、装饰者模式的应用场景

装饰者模式通常适用于以下场景:

  1. 在不影响现有对象结构的情况下,动态地添加额外的功能或行为。

  2. 需要扩展一个类的功能,但是使用继承会导致类的数量增加,且不利于维护。

  3. 需要在不修改代码的情况下,对对象的某些功能进行组合或移除。

  4. 需要对一个对象的功能进行多次扩展或组合,而不是一次性地进行全部扩展或组合。

  5. 需要在运行时动态地添加或删除对象的功能。

  6. 需要在不破坏封装性的前提下,对对象的功能进行扩展或修改。

  7. 需要对对象的功能进行动态排序或过滤。

  8. 需要对对象的功能进行动态配置或组合。

总之,装饰者模式适用于需要动态地添加或删除对象的功能,同时又不希望对现有对象结构进行修改的场景。

4、装饰者模式的结构

装饰者模式的结构包括以下组件:

  1. 抽象组件(Component):定义了组件的接口,可以是抽象类或接口。

  2. 具体组件(Concrete Component):实现了抽象组件的接口,提供了基本的功能。

  3. 抽象装饰者(Decorator):定义了装饰者的接口,包含一个指向抽象组件的引用。

  4. 具体装饰者(Concrete Decorator):实现了抽象装饰者的接口,对抽象组件添加了新的功能。

装饰者模式使用组合而非继承的方式,动态地将责任附加到对象上,从而实现了动态地扩展对象的功能。它可以在不修改现有代码的情况下,动态地添加或删除对象的功能,同时避免了使用子类来扩展对象的功能,从而减少了类的数量。

5、装饰者模式的代码案例

假设有一个饮料类(Beverage),它有一个描述(description)和一个计算价格(cost)的方法。现在需要给这个饮料类添加一些调料(Condiment),比如牛奶、摩卡等,这些调料也有自己的描述和价格。使用装饰者模式,可以动态地添加或删除调料,而不需要修改饮料类的代码。

首先,我们定义一个饮料类Beverage,它是一个抽象类,包含描述和计算价格两个方法:

package com.pany.camp.design.principle.decorators;

/**
 *
 * @description: 抽象类
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-27 20:37
 */
public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

然后,我们定义一个具体的饮料类Espresso,它继承自Beverage类,实现了cost方法和description属性:

package com.pany.camp.design.principle.decorators;

/**
 *
 * @description:  抽象实现
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 20:38
 */
public class Espresso extends Beverage {
    public Espresso() {
        description = "Espresso";
    }
    public double cost() {
        return 1.99;
    }
}

接下来,我们定义一个抽象的调料类CondimentDecorator,它也是一个抽象类,继承自Beverage类,包含一个抽象的getDescription方法:

package com.pany.camp.design.principle.decorators;

/**
 *
 * @description:  抽象的调料类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 20:38
 */
public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

然后,我们定义一个具体的调料类Milk,它继承自CondimentDecorator类,包含一个Beverage类型的成员变量和一个构造方法,用于接收一个饮料对象,然后将其保存到成员变量中。getDescription方法会调用Beverage对象的getDescription方法,并在其后面添加", Milk"。cost方法会调用Beverage对象的cost方法,并加上0.10的价格:

package com.pany.camp.design.principle.decorators;

/**
 *
 * @description:  具体的调料类Milk
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 20:39
 */
public class Milk extends CondimentDecorator {
    Beverage beverage;

    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Milk";
    }

    public double cost() {
        return beverage.cost() + 0.10;
    }
}

类似地,我们定义另一个具体的调料类Mocha,它也继承自CondimentDecorator类,包含一个Beverage类型的成员变量和一个构造方法,用于接收一个饮料对象,然后将其保存到成员变量中。getDescription方法会调用Beverage对象的getDescription方法,并在其后面添加", Mocha"。cost方法会调用Beverage对象的cost方法,并加上0.20的价格:

package com.pany.camp.design.principle.decorators;

/**
 *
 * @description:  具体的调料类Mocha
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 20:40 
 */
public class Mocha extends CondimentDecorator {
    Beverage beverage;

    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    public double cost() {
        return beverage.cost() + 0.20;
    }
}

最后,我们可以使用如下的测试代码来测试我们的装饰者模式:

package com.pany.camp.design.principle.decorators;

/**
 * @description: 客户端
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-27 20:40
 */
public class Client {

    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
        beverage = new Milk(beverage);
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
        beverage = new Mocha(beverage);
        System.out.println(beverage.getDescription() + " $" + beverage.cost());
    }
}

输出结果为:

Espresso $1.99
Espresso, Milk $2.09
Espresso, Milk, Mocha $2.29

Process finished with exit code 0

可以看到,通过装饰者模式,我们动态地给饮料类添加了调料,而不需要修改饮料类的代码。
深入浅出设计模式 - 装饰者模式

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊
深入浅出设计模式 - 装饰者模式文章来源地址https://www.toymoban.com/news/detail-503608.html

到了这里,关于深入浅出设计模式 - 装饰者模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《深入浅出.NET框架设计与实现》笔记1——.NET CLI 概述

    .NET CLI(NET 命令行接口)工具是用于开发生成运行和发布.NET应用程序的跨平台工具链。 默认安装的命令有 1、基本命令 2、项目修改命令 3、高级命令 4、工具管理命令 工具三控制台应用程序,它们从NuGet包中安装并从命令提示符处进行调用。 CLI命令结构包 含驱动程序(“

    2024年04月22日
    浏览(39)
  • 【动手学深度学习】深入浅出深度学习之RMSProp算法的设计与实现

    目录 🌞一、实验目的 🌞二、实验准备 🌞三、实验内容 🌼1. 认识RMSProp算法 🌼2. 在optimizer_compare_naive.py中加入RMSProp 🌼3. 在optimizer_compare_mnist.py中加入RMSProp 🌼4. 问题的解决 🌞四、实验心得 深入学习RMSProp算法的原理和工作机制; 根据RMSProp算法的原理,设计并实现一个

    2024年04月10日
    浏览(37)
  • 设计模式-装饰器模式

    装饰者模式的定义为:动态的给一个对象添加其它功能。 从扩展性来说,这种方式比继承更有弹性,更加灵活,装饰者模式也体现了开闭原则(OCP)。 星巴克咖啡订单项目(咖啡馆) : 1)咖啡种类/单品咖啡: Espresso(意大利浓咖啡)、ShortBlack、Decaf(无因咖啡)、LongBlack(美式咖啡) 2)

    2024年02月06日
    浏览(33)
  • 设计模式——装饰者模式

    更多内容,前往 IT-BLOG 现实生活中常常需要给某类产品动态增加新的功能,如:给面条各种调味品。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成一些核心功能。但在不改变其架构的情况下,可以动态地扩展其功能。所以这些都可以采用装饰模式来实

    2024年02月22日
    浏览(26)
  • 设计模式--装饰者模式

    (1) 可乐种类/单品可乐 :BaiShiCola(百事可乐) FeiChangCola(非常可乐) CoCola(可口可乐) (2) 调料/附品: Milk  Chocolate (3) 要求在扩展新的可乐种类时 要具有良好的扩展性 改动方便 维护方便 (4) 使用OO的来就算不同之类可乐的费用 客户可以点单品可乐 也可以单品可乐+调料组合 方案1 

    2024年02月02日
    浏览(31)
  • 设计模式(3)装饰模式

    一、介绍: 1、应用场景:把所需的功能按正确的顺序串联起来进行控制。动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是

    2024年02月13日
    浏览(30)
  • 设计模式——装饰器模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。 这种模式创建了一个装饰类,用来包装原有的

    2024年02月10日
    浏览(30)
  • 【设计模式】-装饰器模式

    在软件开发中,经常有需求对已有的对象进行功能的扩展,但是传统的继承方式会导致类的数量快速增多,且难以维护。为了解决这个问题,装饰器模式应运而生。 装饰器模式是一种结构型设计模式,它可以在运行时动态地将新的行为附加到对象上,而不改变其结构。这种方

    2024年02月14日
    浏览(26)
  • 【设计模式】装饰器模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。 这种模式创建了一个装饰类,用来包装原有的

    2024年02月13日
    浏览(28)
  • 设计模式之装饰者模式

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

    2024年02月09日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包