设计模式--》 装饰模式的应用

装饰模式的定义:

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

何时应用装饰模式?

1.当需要动态地给一个对象增加功能时:如果你需要在运行时给一个对象增加新的职责,而不是在编译时,那么装饰模式是一个好的选择。

2.当使用继承会导致大量子类时:如果你使用继承来扩展对象的功能,那么可能会产生大量的子类,导致系统难以管理和维护。使用装饰模式可以避免这个问题。

3.当需要透明地增强对象的功能时:装饰模式允许你透明地增强对象的功能,这意味着客户端代码可以像使用原始对象一样使用装饰后的对象,而不需要知道对象已经被装饰了。

需要注意什么?

  1. 避免过度使用:虽然装饰模式很灵活,但过度使用它可能会导致代码变得复杂和难以理解。因此,在决定是否使用装饰模式时,需要权衡其优点和缺点。

  2. 性能考虑:由于装饰模式会在运行时动态地添加功能,因此可能会带来一些性能开销。如果性能是一个关键问题,那么需要仔细考虑是否使用装饰模式。

  3. 设计好接口:装饰模式依赖于良好的接口设计。如果接口设计得不好,那么装饰模式可能会变得难以使用和维护。

重要的构造部分:

  1. 组件(Component):这是一个接口或抽象类,它定义了对象的核心职责。

  2. 具体组件(ConcreteComponent):这是实现了组件接口的具体类。

  3. 装饰器(Decorator):这也是一个接口或抽象类,它实现了组件接口,并持有一个对组件对象的引用。装饰器接口通常会增加一些新的方法或覆盖组件接口中的方法,以提供额外的功能。

  4. 具体装饰器(ConcreteDecorator):这是实现了装饰器接口的具体类。具体装饰器会持有对组件对象的引用,并在需要时调用组件对象的方法。同时,具体装饰器还可以添加自己的功能。

  5. 客户端(Client):客户端代码通过组件接口与对象交互,而不需要知道对象是否被装饰了。

示例实现:

以下是一个简单的装饰模式示例,它模拟了一个咖啡订单系统。在这个系统中,可以为咖啡添加不同的调料,如牛奶和糖,这些调料就是装饰器。

首先,定义一个Beverage接口,它代表了一种饮料:

public interface Beverage {  String getDescription();  double cost();  
}

接着,创建一个实现了Beverage接口的DarkRoast类,它代表了一种深焙咖啡:

public class DarkRoast implements Beverage {  @Override  public String getDescription() {  return "Dark Roast Coffee";  }  @Override  public double cost() {  return 1.99;  }  
}

现在创建一个CondimentDecorator抽象类,它实现了Beverage接口并持有一个Beverage对象的引用。这个类将作为所有装饰器的基类:

public abstract class CondimentDecorator implements Beverage {  protected Beverage beverage;  public CondimentDecorator(Beverage beverage) {  this.beverage = beverage;  }  @Override  public String getDescription() {  return beverage.getDescription();  }  @Override  public double cost() {  return beverage.cost();  }  
}

接下来创建两个具体的装饰器类:Milk和Sugar,它们分别表示加牛奶和加糖的调料:


//milk类
public class Milk extends CondimentDecorator {  public Milk(Beverage beverage) {  super(beverage);  }  @Override  public String getDescription() {  return beverage.getDescription() + ", Milk";  }  @Override  public double cost() {  return beverage.cost() + 0.20; // 假设加牛奶要额外收费0.2美元  }  
}  //suger类 
public class Sugar extends CondimentDecorator {  public Sugar(Beverage beverage) {  super(beverage);  }  @Override  public String getDescription() {  return beverage.getDescription() + ", Sugar";  }  @Override  public double cost() {  return beverage.cost() + 0.10; // 假设加糖要额外收费0.1美元  }  
}

最后创建一个客户端类来演示如何使用装饰模式:

public class CoffeeShop {  public static void main(String[] args) {  Beverage beverage = new DarkRoast();  System.out.println(beverage.getDescription() + " $" + beverage.cost());  Beverage beverageWithMilk = new Milk(new DarkRoast());  System.out.println(beverageWithMilk.getDescription() + " $" + beverageWithMilk.cost());  Beverage beverageWithSugarAndMilk = new Milk(new Sugar(new DarkRoast()));  System.out.println(beverageWithSugarAndMilk.getDescription() + " $" + beverageWithSugarAndMilk.cost());  }  
}

最后运行代码会显示:

Dark Roast Coffee $1.99  
Dark Roast Coffee, Milk $2.19  
Dark Roast Coffee, Sugar, Milk $2.29

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

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

相关文章

《C语言深度解剖》(15):动态内存管理和柔性数组

🤡博客主页:醉竺 🥰本文专栏:《C语言深度解剖》 😻欢迎关注:感谢大家的点赞评论关注,祝您学有所成! ✨✨💜💛想要学习更多C语言深度解剖点击专栏链接查看&…

k8s中的集群调度

文章目录 k8s中的集群调度Pod 创建流程 通过指定节点来创建pod所在的node节点通过标签来指定pod创建在哪个节点上pod 的亲和性Pod的亲和性和反亲和性亲和性(Affinity)反亲和性(Anti-Affinity) 污点与容忍污点(Taint&am…

Spring Cache入门详解

一、概述 1.1缓存介绍 Spring提供了一套cache缓存抽象(注解/接口),使基于spring缓存的使用与实现解耦 默认实现,Spring JDK ConcurrentMap-based Cache第三方实现,caffeine/Ehcache/Redis等 https://docs.spring.io/spring-framework/do…

Postman快捷功能-快速填写请求头

大家好,之前给大家分享关于 Postman 工具的基础使用,今天给大家介绍一个快捷功能,可以一定程度提高我们使用 Postman 工具的效率,在我们进行接口测试时,几乎每个接口都需要填写 Headers,且 Headers 中的参数…

【ai】livekit服务本地开发模式2:模拟1个发布者

是一个会议用软件:LiveKit is an open source project that provides scalable, multi-user conferencing based on WebRTC. It’s designed to provide everything you need to build real-time video audio data capabilities in your applications.LiveKit’s server is wr…

【Python】 Django 框架如何支持百万级日访问量

基本原理 Django 是一个高级的 Python Web 框架,它鼓励快速开发和干净、实用的设计。Django 遵循 MVC(模型-视图-控制器)设计模式,允许开发者通过编写更少的代码来构建高质量的 Web 应用程序。Django 自带了许多内置功能&#xf…

发现没:随便搞个B端页面,就想在客户那里过关,难啦。

客户对B端界面要求越来越高的原因可以有以下几点: 用户体验要求提升:随着用户对移动应用和网页的使用经验增加,他们对于界面的交互、流畅性和易用性要求也越来越高。他们希望能够在使用B端应用时,能够快速、方便地完成任务&#…

2024年华为OD机试真题-文本统计分析-C++-OD统一考试(C卷D卷)

题目描述: 有一个文件, 包含以一定规则写作的文本, 请统计文件中包含的文本数量 规则如下 1. 文本以";"分隔,最后一条可以没有";",但空文本不能算语句,比如"COMMAND A; ;"只能算一条语句. 注意, 无字符/空白字符/制表符都算作"空&qu…

设计模式详解(六):适配器模式——Adapter

目录导航 适配器模式及其作用现实生活举例 适配器模式的好处适配器模式的实现关系图实现步骤 适配器模式的适用场景适配器模式示例 适配器模式及其作用 适配器模式是一种结构型设计模式。所谓结构型是指在代码结构方面的设计模式。适配器模式作为中间层,可以让交互…

Vue3 图片或视频下载跨域或文件损坏的解决方法

Vue3 图片或视频下载跨域或文件损坏的解决方法 修改跨域配置文件下载方法 修改跨域配置文件 修改vite.config.ts文件proxy里面写跨域地址,如下图,图片地址就是我们要跨域的目标地址: 下载方法 如下就是我取消上面那句后的报错 然后调用两…

【C++风云录】C++与智能交通:智能交通系统与车联网

解锁C的力量:在智能交通系统与车联网中使用关键库 前言 本文关注于C在智能交通系统与车联网中的应用,并提供了五个常见库的简介和使用方法。这些库包括:Veins, SUMO-GUI, OMNeT, NS-3和PLEXE,每个库都有其独特的功能和优点&…

【Java】Sping Boot中使用Javax Bean Validation

目录 Javax Bean Validation在Spring Boot中集成Javax Bean Validation使用案例功能测试配置全局异常处理器重新测试返回特定形式的信息方式一方式二 附:常用的注解 Javax Bean Validation Javax Bean Validation是Java平台的一项规范,旨在提供一种简单…

想知道股指期货和期权有什么不同吗?

市场上目前有中金所的沪深300ETF,中证500和中证1000股指期货,期权市场有上证50ETF,沪深300etf和中证500ETF期权,股指期货和期权在买卖双方的权利义务、风险收益特征、保证金制度、上市合约数量等方面均有较大区别,下文…

每天学点小知识:Windows终端Powershell美化

前言 本章的旨在教会你美化自己的终端,powershell需要以管理员运行 经过我的测试,不同的电脑可能会有不同的报错,具体操作根据官方为主https://ohmyposh.dev/docs 效果展示 Oh My Posh:提供美观的 PowerShell 提示符主题 1.安装…

揭秘CISA:你不知道的信息安全认证,轻松掌握职场先机!

在当今的信息化时代,信息系统的安全和稳定是企业和组织的重要资产。信息系统审计是一项专业的工作,需要具备丰富的知识和经验,以及敏锐的洞察力和判断力。信息系统审计师是信息系统审计领域的专业人士,他们负责对信息系统的设计、…

MVVM模式的优点以及与MVC模式的区别?

1.MVVM 模式的优点: 1 、低耦合: 视图( View )可以独⽴于 Model 变化和修改,⼀个 ViewModel 可以绑定到不同的 "View" 上,当 View 变化的时候 Model 可以不变,当 Model 变化的时…

【OpenGL实践12】关于缓存区Framebuffer的运用

文章目录 一、说明二、帧缓冲区三、创建新的帧缓冲区四、附属装饰4.1 纹理图像4.2 渲染缓冲区对象图像 五、使用帧缓冲区5.1 后期处理5.2 更改代码 六、后期处理效果6.1 色彩处理6.2 模糊6.3 Sobel算子 七、结论练习 一、说明 关于FrameBuffer的使用,是OpenGL的高级…

横截面分位数回归

一、分位数回归简介 分位数回归(英语:Quantile regression)是回归分析的方法之一。最早由Roger Koenker和Gilbert Bassett于1978年提出。一般地,传统的回归分析研究自变量与因变量的条件期望之间的关系,相应得到的回归…

AI时代的服装设计师--AIGC

AI时代的服装设计师--AIGC AIGCAIGC设计能替代真正的设计师吗森马T恤设计AIGC优势、优化 本文记录于去年参加的一次森马T恤设计活动的感受。 AIGC 可以说,近期以来,随着ChatGPT的不断发展,从ChatGPT-3到ChatGPT-4的飞速发展,AIGC…

Windows和Linux系统部署Docker(2)

目录 一、Linux系统部署docker 前置环境: 1.安装需要的软件包, yum-util 提供yum-config-manager功能 2.添加阿里云 docker-ce 仓库 3.安装docker软件包 4.启动 docker并设置开机自启 5.查看版本: 二、windows系统部署docker 1.查看…