java 语言写一个装饰器模式代码

装饰器模式(Decorator Pattern)允许你动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。下面是一个简单的 Java 装饰器模式的示例代码:

首先,我们定义一个接口 Component

public interface Component {void operation();
}

然后,我们创建一个实现了 Component 接口的 ConcreteComponent 类:

public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("执行具体组件的操作");}
}

接下来,我们创建一个抽象装饰器类 Decorator,它同样实现了 Component 接口,并持有对 Component 对象的引用:

public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {if (component != null) {component.operation();}}
}

现在,我们可以创建具体的装饰器类,它们扩展了 Decorator 类并添加了额外的功能:

public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {super.operation(); // 调用原始组件的操作addedFunctionA(); // 添加额外的功能A}private void addedFunctionA() {System.out.println("添加功能A");}
}public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {super.operation(); // 调用原始组件或之前装饰器的操作addedFunctionB(); // 添加额外的功能B}private void addedFunctionB() {System.out.println("添加功能B");}
}

最后,我们使用这些类来展示装饰器模式的工作方式:

public class DecoratorPatternDemo {public static void main(String[] args) {Component component = new ConcreteComponent();// 创建装饰器,并将具体组件作为参数传递Component decoratorA = new ConcreteDecoratorA(component);Component decoratorAB = new ConcreteDecoratorB(decoratorA);// 执行操作,将调用所有的功能,包括原始组件和装饰器添加的功能decoratorAB.operation();}
}

运行 DecoratorPatternDemomain 方法,你将看到如下输出:

执行具体组件的操作
添加功能A
添加功能B

这个示例展示了如何使用装饰器模式动态地给一个对象(这里是 ConcreteComponent)添加功能(ConcreteDecoratorAConcreteDecoratorB)。你可以通过创建更多的装饰器类来添加更多的功能,而无需修改原始组件的代码。


装饰器模式和生成器模式相比有什么优缺点呢

装饰器模式和生成器模式在软件设计中各有其优缺点,它们解决的问题和目的也有所不同。以下是它们之间的主要比较:

装饰器模式

优点:

  1. 更高的灵活性:装饰器模式可以在不修改原始类的情况下,动态地给对象添加新的功能或责任。这使得代码更加灵活,易于扩展。
  2. 开闭原则:装饰器模式符合开闭原则,即在不修改原有代码的基础上,增加新的功能。这有助于保持代码的稳定性和可维护性。
  3. 功能组合:通过不同的装饰器组合,可以创建出具有不同功能组合的对象,从而实现更多的功能组合和扩展。

缺点:

  1. 增加系统复杂性:使用装饰器模式可能会产生很多小对象,这些对象之间的区别在于它们如何相互连接,而不是它们的类或属性值。这可能会增加系统的复杂性。
  2. 易于出错:由于装饰器模式提供了更多的灵活性,因此也更容易出错。特别是当对象被多次装饰时,调试时寻找错误可能需要逐级排查,较为繁琐。

生成器模式

优点:

  1. 代码复用性:生成器模式允许使用相同的构建过程来创建不同的表示形式,从而提高了代码的复用性和灵活性。
  2. 松散耦合:生成器模式可以将产品构建和产品表现分离,实现松散的耦合关系。这使得系统更加易于扩展和维护。

缺点:

  1. 设计复杂性:生成器模式需要设计复杂的构建算法和构建器类,这可能会增加系统的设计复杂性。
  2. 可能的过度使用:如果不恰当地使用生成器模式,可能会导致过度设计,使得系统变得复杂且难以维护。

总结

装饰器模式和生成器模式各有其优缺点,适用于不同的场景。装饰器模式主要用于在不修改原始类的情况下,动态地给对象添加新的功能或责任,适用于需要灵活扩展功能的场景。而生成器模式则主要用于使用相同的构建过程来创建不同的表示形式,提高代码的复用性和灵活性,适用于需要创建复杂对象并控制其构建过程的场景。在选择使用哪种模式时,需要根据具体的需求和场景来综合考虑。


在实际项目中,哪一种设计模式更常见呢

在实际项目中,装饰器模式和生成器模式的使用频率取决于项目的具体需求和上下文。然而,一般来说,装饰器模式在以下场景中更为常见:

  1. 动态功能扩展:当需要在运行时动态地给对象添加新功能或责任时,装饰器模式非常有用。例如,在GUI编程中,你可能需要动态地为按钮添加额外的行为(如禁用、高亮显示等),而不需要修改按钮的原始类。

  2. 责任链:装饰器模式可以很容易地实现责任链模式,其中每个装饰器都可以选择是否将请求传递给下一个装饰器或自己处理。这在处理具有多个可选步骤的流程时非常有用。

  3. 日志和审计:在需要记录对象操作的日志或进行审计的场景中,装饰器模式可以很容易地添加日志记录或审计功能,而无需修改原始对象的代码。

生成器模式在以下场景中更为常见:

  1. 复杂对象的构建:当需要构建复杂对象,并且这些对象的构建过程具有许多可选步骤或配置时,生成器模式非常有用。例如,在构建汽车时,你可以选择不同的引擎、颜色、轮胎等配置,生成器模式可以很容易地处理这些不同的配置选项。

  2. 构建顺序的控制:生成器模式允许你控制对象的构建顺序,确保在正确的时间点执行正确的操作。这在需要按照特定顺序执行多个步骤的场景中非常有用。

  3. 框架和库:在构建框架或库时,生成器模式可以提供一个灵活的方式来创建不同类型的对象,而无需在框架或库中硬编码这些对象的创建逻辑。

需要注意的是,虽然装饰器模式和生成器模式在某些方面有所重叠(例如,它们都可以用于创建具有不同配置的对象),但它们的侧重点和用途是不同的。因此,在选择使用哪种模式时,应该根据项目的具体需求和上下文来综合考虑。

此外,在实际项目中,许多设计模式可能会一起使用,以构建出更加健壮、灵活和可维护的代码库。因此,了解并熟悉多种设计模式是非常重要的。

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

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

相关文章

The 2021 Sichuan Provincial Collegiate Programming Contest

The 2021 Sichuan Provincial Collegiate Programming Contest The 2021 Sichuan Provincial Collegiate Programming Contest A. Chuanpai 题意:给出总值k,将k分成xyk,x和y均小于7,最多分成多少组。 思路:暴力跑一…

【工具】Office/WPS 插件|AI 赋能自动化生成 PPT 插件测评 —— 必优科技 ChatPPT

本文参加百度的有奖征文活动,更主要的也是借此机会去体验一下 AI 生成 PPT 的产品的现状,因此本文是设身处地从用户的角度去体验、使用这个产品,并反馈最真实的建议和意见,除了明确该产品的优点之外,也发现了不少缺陷和…

实战Java虚拟机-基础篇

JVM的组成 一、自动垃圾回收 1.Java的内存管理 Java中为了简化对象的释放,引入了自动的垃圾回收(Garbage Collection简称GC)机制。通过垃圾回收器来对不再使用的对象完成自动的回收,垃圾回收器主要负责对堆上的内存进行回收。其…

vue项目基于WebRTC实现一对一音视频通话

效果 前端代码 <template><div class"flex items-center flex-col text-center p-12 h-screen"><div class"relative h-full mb-4 fBox"><video id"localVideo"></video><video id"remoteVideo">…

firewall-cmd --list-all详解

含义 在 firewall-cmd --list-all 命令的输出结果中&#xff0c;涉及到的每行的含义如下&#xff1a; “target”&#xff1a;表示当前 Firewalld 防火墙的默认目标&#xff0c;可以是 “ACCEPT”、“DROP” 或 “REJECT”。 “DROP”&#xff0c;表示拒绝所有流量&#xff1…

App拍照,照片压缩存储到app内部,同步更新手机系统相册

H5页面调用安卓相机拍照&#xff0c;然后在H5页面显示&#xff1a; 1、H5调用相机的回调&#xff1a; binding.fragmentWebWebview.setWebChromeClient(new WebChromeClient() {Overridepublic boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePa…

2024Windows11最新安装pyspider

1、创建conda虚拟环境 conda create -n _pyspider python==3.6虚拟环境建好后会自动有 wheel库2、配置phantom浏览器 参考phantom安装 3、conda安装pycurl conda install pycurl4、一次性安装各种依赖 requirements.txt内容如下: Flask==0.10 Jinja2==2.7 chardet==3.0.…

【MQTT】服务端、客户端工具使用记录

目录 一、服务端 1.1 下载 1.2 相关命令 &#xff08;1&#xff09;启动 &#xff08;2&#xff09;关闭 &#xff08;3&#xff09;修改用户名和密码 1.3 后台管理 &#xff08;1&#xff09;MQTT配置 &#xff08;2&#xff09;集群概览 &#xff08;3&#xff09;…

livox雷达斜装修改

fast_lio中的mid360.yaml中的外参 extrinsic_est_en: false # true: enable the online estimation of IMU-LiDAR extrinsicextrinsic_T: [ -0.011, -0.02329, 0.04412 ]extrinsic_R: [ 1, 0, 0,

基于内容的推荐方法有哪些实施难点

1、特征提取的复杂性&#xff1a; 基于内容的推荐方法依赖于从用户行为和物品属性中提取的有效特征。然而&#xff0c;对于文本、视频、音频等多媒体内容&#xff0c;特征提取往往较为复杂&#xff0c;需要专业的领域知识和高效的算法。此外&#xff0c;提取的特征的质量直接影…

如何使用SkyWalking收集分析分布式系统的追踪数据

Apache SkyWalking 是一个开源的观测性工具&#xff0c;用于收集、分析和展示分布式系统的追踪数据。SkyWalking 支持多种语言的追踪&#xff0c;包括但不限于 Java、.NET、Node.js 等。以下是使用 SkyWalking 工具实现数据采集的详细步骤&#xff1a; 1. 下载和安装 SkyWalkin…

数据挖掘算法原理与实践:决策树

第2关&#xff1a;决策树算法原理 任务描述 本关任务&#xff1a;根据本关所学知识&#xff0c;完成 calcInfoGain 函数。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 信息熵&#xff1b;条件熵&#xff1b;信息增益。 信息熵 信息是个很抽象的概念。…

代码随想录算法训练营第六十一天| 739. 每日温度,496.下一个更大元素 I

题目与题解 739. 每日温度 题目链接&#xff1a;739. 每日温度 代码随想录题解&#xff1a;739. 每日温度 视频讲解&#xff1a;单调栈&#xff0c;你该了解的&#xff0c;这里都讲了&#xff01;LeetCode:739.每日温度_哔哩哔哩_bilibili 解题思路&#xff1a; 最好想的就是暴…

Flink面试整理-Flink常见API

Apache Flink 提供了多种 API,使开发者能够方便地实现复杂的数据处理和分析任务。以下是 Flink 中一些常见的 API: DataStream API:用于构建实时流处理应用程序。支持事件时间(Event Time)、摄取时间(Ingestion Time)和处理时间(Processing Time)的概念。提供丰富的操…

风电厂数字孪生3D数据可视化交互展示构筑智慧化电厂管理体系

随着智慧电厂成为未来电力企业发展的必然趋势&#xff0c;深圳华锐视点紧跟时代步伐&#xff0c;引领技术革新&#xff0c;推出了能源3D可视化智慧管理系统。该系统以企业现有的数字化、信息化建设为基础&#xff0c;融合云平台、大数据、物联网、移动互联、机器人、VR虚拟现实…

Android 右键 new AIDL 无法选择

提示 (AIDL File)Requires setting the buildFeatures.aidl to true in the build file&#xff09; 解决方式&#xff1a; 在app的build.gradl中 adnroid{} 添加&#xff1a; buildFeatures{aidl true}

Oracle-一次TX行锁堵塞事件

问题背景&#xff1a; 接用户问题报障&#xff0c;应用服务出现大量会话堆积现象&#xff0c;数据库锁堵塞严重&#xff0c;需要协助进行问题定位和排除。 问题分析&#xff1a; 登录到数据库服务器上&#xff0c;首先查看一下数据库当前的等待事件情况&#xff0c;通过gv$ses…

Java|用爬虫解决问题

使用Java进行网络爬虫开发是一种常见的选择&#xff0c;因为Java语言的稳定性和丰富的库支持使得处理网络请求、解析HTML/XML、数据抓取等任务变得更加便捷。下面是一个简单的Java爬虫示例&#xff0c;使用了Jsoup库来抓取网页内容。这个示例将展示如何抓取一个网页的标题。 准…

教你零成本,免费使用comfyui复现remini爆火的黏土风格转绘(附完整教程)

在五一假期期间,一款名为Remini的AI照片编辑软件在小红书上迅速走红,其独特的“丑萌”黏土风格滤镜深受广大博主和用户的喜爱,引发了一波热潮,让人们玩得不亦乐乎。 Remini软件提供的这种视觉效果虽然看起来有点“丑萌”特效,然而,正是这种独树一帜的画风,使得Remini迅速…

【Django学习笔记(十)】Django的创建与运行

Django的创建与运行 前言正文1、安装Django2、创建项目2.1 基于终端创建项目2.2 基于Pycharm创建项目2.3 两种方式对比 3、默认项目文件介绍4、APP5、启动运行Django5.1 激活App5.2 编写URL和视图函数对应关系5.3 启动Django项目5.3.1 命令行启动5.3.2 Pycharm启动5.3.3 views.…