当前位置: 首页 > news >正文

GPT带我学-设计模式17-装饰器模式

概述

装饰器模式(Decorator Pattern)是一种结构型设计模式,允许你在不改变对象接口的前提下,动态地给对象添加新功能。这个模式通常用于扩展类的功能。

基本结构

  1. 组件接口(Component):定义一个接口,包含基本的方法。
  2. 具体组件(ConcreteComponent):实现组件接口的类,是被装饰的对象。
  3. 装饰器(Decorator):实现组件接口,并持有一个组件的引用,通常会重写接口中的方法来添加新功能。
  4. 具体装饰器(ConcreteDecorator):继承装饰器类,增加具体的功能。

示例代码

假设我们有一个简单的文本组件,我们希望添加一些装饰,比如加粗和斜体。

// 组件接口
interface Text {String getContent();
}// 具体组件
class SimpleText implements Text {private String content;public SimpleText(String content) {this.content = content;}@Overridepublic String getContent() {return content;}
}// 装饰器
abstract class TextDecorator implements Text {protected Text decoratedText;public TextDecorator(Text decoratedText) {this.decoratedText = decoratedText;}@Overridepublic String getContent() {return decoratedText.getContent();}
}// 具体装饰器:加粗
class BoldDecorator extends TextDecorator {public BoldDecorator(Text decoratedText) {super(decoratedText);}@Overridepublic String getContent() {return "<b>" + decoratedText.getContent() + "</b>";}
}// 具体装饰器:斜体
class ItalicDecorator extends TextDecorator {public ItalicDecorator(Text decoratedText) {super(decoratedText);}@Overridepublic String getContent() {return "<i>" + decoratedText.getContent() + "</i>";}
}// 使用示例
public class Main {public static void main(String[] args) {Text simpleText = new SimpleText("Hello, World!");Text boldText = new BoldDecorator(simpleText);Text italicText = new ItalicDecorator(boldText);System.out.println(italicText.getContent());  // 输出:<i><b>Hello, World!</b></i>}
}

优点

  • 灵活性:可以按需组合装饰,增加或减少功能。
  • 遵循单一职责原则:每个装饰器负责一项功能。

缺点

  • 复杂性:增加了系统的复杂性,使用过多装饰器可能导致代码难以理解。
  • 性能问题:由于多层装饰,可能会引入一些性能开销。

希望这个介绍和示例对你理解装饰器模式有所帮助!如果你有任何问题,欢迎随时问我。

示例2 在线购物系统中的订单处理示例

一个在线购物系统中的订单处理示例。在这个例子中,我们将通过装饰器模式动态添加不同的费用,比如运费和税费。

结构

  1. 订单接口(Order):定义一个接口,表示订单的基本功能。
  2. 具体订单(BasicOrder):实现订单接口的基本订单。
  3. 装饰器(OrderDecorator):实现订单接口,持有一个订单的引用。
  4. 具体装饰器(ShippingDecorator, TaxDecorator):分别添加运费和税费。

示例代码

// 订单接口
interface Order {double getCost();
}// 具体订单
class BasicOrder implements Order {private double cost;public BasicOrder(double cost) {this.cost = cost;}@Overridepublic double getCost() {return cost;}
}// 装饰器
abstract class OrderDecorator implements Order {protected Order decoratedOrder;public OrderDecorator(Order decoratedOrder) {this.decoratedOrder = decoratedOrder;}@Overridepublic double getCost() {return decoratedOrder.getCost();}
}// 具体装饰器:运费
class ShippingDecorator extends OrderDecorator {private double shippingCost;public ShippingDecorator(Order decoratedOrder, double shippingCost) {super(decoratedOrder);this.shippingCost = shippingCost;}@Overridepublic double getCost() {return decoratedOrder.getCost() + shippingCost;}
}// 具体装饰器:税费
class TaxDecorator extends OrderDecorator {private double taxRate;public TaxDecorator(Order decoratedOrder, double taxRate) {super(decoratedOrder);this.taxRate = taxRate;}@Overridepublic double getCost() {return decoratedOrder.getCost() + (decoratedOrder.getCost() * taxRate);}
}// 使用示例
public class Main {public static void main(String[] args) {Order order = new BasicOrder(100.0);  // 基本订单// 添加运费order = new ShippingDecorator(order, 10.0);// 添加税费order = new TaxDecorator(order, 0.15);  // 15% 税率System.out.println("总费用: " + order.getCost());  // 输出:总费用: 126.5}
}

总结

在这个例子中,装饰器模式允许我们根据需要动态地为基本订单添加运费和税费,而无需修改基本订单的结构。这种灵活性在处理不同类型的订单时非常有用。如果你有其他问题或需要更深入的讨论,请告诉我!

相关文章:

GPT带我学-设计模式17-装饰器模式

概述 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;允许你在不改变对象接口的前提下&#xff0c;动态地给对象添加新功能。这个模式通常用于扩展类的功能。 基本结构 组件接口&#xff08;Component&#xff09;&#xff1a;定义一…...

【Redis】如何在 Ubuntu 上安装 Redis 5

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 本期内容主要介绍如何在 Ubuntu 上安装 Redis5 一些碎碎念&#xff1a; 本来这期内容介绍如何在 Centos 安装 Redis …...

房屋水电费记账本:内置的数组数据击按钮不能删除,页面手动添加的可以删除

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>房租水电费记录</title><script type&qu…...

【ubuntu】apt是什么

目录 1.apt简介 2.常用apt指令 2.1安装 2.2更新列表 2.3更新已经安装的软件包 2.4搜索软件包 2.5显示软件包信息 2.6移除软件包 2.7清理无用的安装包 2.8清理无用的依赖项 3.apt和apt-get 3.1区别 3.2 总结 1.apt简介 apt的全称是advanced package …...

堆排序算法的原理与应用

堆排序&#xff08;Heap Sort&#xff09;是一种基于堆数据结构的比较排序算法。它具有时间复杂度为 O(n log n) 的优点&#xff0c;并且空间复杂度为 O(1)&#xff0c;是一种不稳定的排序算法。本文将详细介绍堆排序的工作原理、步骤以及它的应用场景。 一、堆排序的基本概念…...

【2024版本】Mac/Windows IDEA安装教程

IDEA 2024版本真的很强大&#xff0c;此外JDK发布了最新稳定版 JDK21 &#xff0c;只有新版本支持JDK 21、JDK22。原来数据库插件不支持redis等一些NoSql的数据库的连接&#xff0c;如果要使用需要自己单独装收费的插件。直接打开idea就很吃内存了&#xff0c;再打开其他一大堆…...

Oracle bbed编译安装及配置

1. 什么是bbed &#xff1f; Oracle Block Brower and EDitor Tool,是一个可以对oracle data block进行查看&#xff0c;编辑修改的内置工具。对于bbed&#xff0c;oracle本身是不提供支持的。 2. 如何编译bbed环境&#xff1f; 10g版本&#xff1a; 1) 编译bbed cd $ORACL…...

MindSearch 部署到Github Codespace 和 Hugging Face Space

conda init后需要重开终端&#xff0c;不然一键复制会导致后续pip install会安装错环境 还是报错 ImportError: cannot import name AutoRegister from class_registry (/opt/conda/envs/mindsearch/lib/python3.10/site-packages/class_registry/__init__.py)pip install --…...

【Maven】依赖管理,Maven仓库,Maven核心功能

Maven 是一个项目管理工具&#xff0c;基于 POM&#xff08;Project Object Model&#xff0c;项目对象模型&#xff09;的概念&#xff0c;Maven 可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的项目管理工具软件 大白话&#xff1a;Maven 是一个项目管理工…...

Android wifi信号和漫游信号设置

1.wifi信号 /packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java Deprecated public static int calculateSignalLevel(int rssi, int numLevels) { if (rssi < MIN_RSSI) { //*/update wifi signal return 1;…...

检查cuda和显卡的可用性

检查cuda和显卡的可用性 import torch device_gpu torch.device(cuda if torch.cuda.is_available() else cpu) print(device_gpu) print(torch.cuda.is_available())...

Kotlin:2.0.20 的新特性

一、概述 Kotlin 2.0.20英文版官方文档 Kotlin 2.0.20发布了!这个版本包括对Kotlin 2.0.0的性能改进和bug修复&#xff0c;我们在其中宣布Kotlin K2编译器为Stable。以下是本次发布的一些亮点: 数据类复制函数将具有与构造函数相同的可见性来自默认目标层次结构的源集的静态访…...

Python内存管理与泄漏排查实战

Python内存管理与泄漏排查实战 Python作为一种高级编程语言&#xff0c;因其易读性和丰富的标准库而备受开发者青睐。然而&#xff0c;随着项目的复杂度增加&#xff0c;内存管理问题可能会影响程序的性能&#xff0c;甚至导致内存泄漏。为了构建健壮且高效的应用程序&#xf…...

828华为云征文|华为云Flexus云服务器X实例搭建部署H5美妆护肤分销商城、前端uniapp

准备国庆之际&#xff0c;客户要搭个 H5 商城系统&#xff0c;这系统好不容易开发好啦&#xff0c;就差选个合适的服务器上线。那可真是挑花了眼&#xff0c;不知道哪款性价比高呀&#xff01;就像在琳琅满目的选择前。最终慧眼识珠&#xff0c;选择了华为云 Flexus X。至于为什…...

初学51单片机之I2C总线与E2PROM二

总结下上篇博文的结论&#xff1a; 1&#xff1a;ACK信号在SCL为高电平期间会一直保持。 2&#xff1a;在字节数据传输过程中如果发送电平跳变&#xff0c;那么电平信号就会变成重复起始或者结束的信号。&#xff08;上篇博文的测试方法还是不能够明确证明这个结论&#xff0…...

Kafka学习笔记(一)Kafka基准测试、幂等性和事务、Java编程操作Kafka

文章目录 前言4 Kafka基准测试4.1 基于1个分区1个副本的基准测试4.2 基于3个分区1个副本的基准测试4.3 基于1个分区3个副本的基准测试 5 Java编程操作Kafka5.1 引入依赖5.2 向Kafka发送消息5.3 从Kafka消费消息5.4 异步使用带有回调函数的生产消息 6 幂等性6.1 幂等性介绍6.2 K…...

结合vueuse实现图片懒加载

介绍 为什么要有懒加载&#xff1f; 在一个网页中如果有很多张图片&#xff0c;那么用户初进这个页面的时候不必一次性把所有图片都加载出来&#xff0c;否则容易造成卡顿和浪费。应该是&#xff0c;用户的视图页面滑到该图片的位置&#xff0c;然后再把该图片加载出来。 前置…...

Mysql数据库--聚合查询、分组查询、联合查询(不同的连接方式)

文章目录 1.查询的进阶版1.1查询搭配插入进行使用1.2聚合查询1.3group by分组查询1.4联合查询之笛卡尔积1.5左外连接&#xff0c;右外连接介绍join on1.6自连表 1.查询的进阶版 1.1查询搭配插入进行使用 我们首先创建两张表&#xff0c;一个叫做student,一个叫做student2,两个…...

计算机视觉——图像修复综述篇

目录 1. Deterministic Image Inpainting 判别器图像修复 1.1. sigle-shot framework (1) Generators (2) training objects / Loss Functions 1.2. two-stage framework 2. Stochastic Image Inpainting 随机图像修复 2.1. VAE-based methods 2.2. GAN-based methods …...

集中式架构和分布式架构

数据是企业的核心资产和战略资源。面对爆炸性的数据增长&#xff0c;如何有效地组织、管理和利用数据成为企业的重大挑战。数据架构作为企业数据管理的蓝图和框架&#xff0c;发挥重要作用。本文就来详细说下当下主流的两种数据架构的类型。 首先明确数据架构定义&#xff1a;…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权

摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题&#xff1a;安全。文章将详细阐述认证&#xff08;Authentication) 与授权&#xff08;Authorization的核心概念&#xff0c;对比传统 Session-Cookie 与现代 JWT&#xff08;JS…...