03-JAVA设计模式-装饰模式

装饰模式

什么装饰模式

装饰器模式(Decorator Pattern)也叫包装器模式,是一种结构型设计模式,允许用户在不改变对象的情况下,动态地给对象增加一些额外的职责(功能)。装饰器模式相比生成子类更为灵活,因为可以在运行时根据需要动态地添加或删除功能。

职责

  • 动态的为一个对象增加新的功能
  • 装饰模式是一种用于替代继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

实现细节

  • 抽象组件(Component):定义一个抽象接口,用于规定准备接收附加责任的对象,即可以给这些对象动态地添加职责。
  • 具体组件(ConcreteComponent):实现了抽象组件的接口,定义了一个具体的“被装饰”对象,这个对象可以被装饰器动态地添加功能。
  • 抽象装饰器(Decorator):继承自抽象组件,并持有一个抽象组件的引用。抽象装饰器中声明了与抽象组件相同的方法,并保留了新增功能的接口,以供具体装饰器添加新的功能。
  • 具体装饰器(ConcreteDecorator):实现抽象装饰器所增加的功能,并在调用原有方法时,增加新的功能。

优点

  • 扩展对象功能,比继承灵活,不会导致类个数的急剧增加
  • 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
  • 具体构件类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。

缺点

  • 产生很多小对象。大量小对象占据内存,一定程度上影响性能
  • 装饰器模式容易出错,调试排查比较麻烦

案例

一台普通通话手机,可扩展出具有拍照功能,NCF功能,联网功能

UML

在这里插入图片描述

实现步骤:

  1. 定义一个抽象组件,用于规定准备接收附加功能/职责的方法IPHONE
  2. 定义一个具体组件,实现抽象组件,及实现具备基础功能/职责
  3. 定义一个抽象装饰器,继承抽象组件,并持有一个抽象组件的引用。实现抽象组件接口方法中调用传入接口组件引用的具体实例的方法,达到调用已具备功能/职责
  4. 定义一个/多个具体装饰器,继承抽象装饰器,增加新功能,实现抽象接口时调用原有方法,及新增功能/职责

实现代码

IPhone.java

// 抽象组件:
// *  定义一个手机具备某种功能接口的抽象类
public interface IPhone {// 具备功能void function();
}

Phone.java

// 具体组件:
// 定义一个具体组件包含最基础的功能:普通手机
public class Phone implements IPhone {@Overridepublic void function(){System.out.println("具备通讯功能");};
}

PhoneExtendFunction.java

//抽象装饰器
// 继承自抽象组件,并持有一个抽象组件的引用
public class PhoneExtendFunction implements IPhone{// 持有一个抽象组件的引用,调用已具有的功能private IPhone phone;public PhoneExtendFunction(IPhone phone) {this.phone = phone;}@Overridepublic void function() {phone.function();}
}

InternetFunction.java

// 具体装饰器
// 实现抽象装饰器所增加的功能,并在调用原有方法时,增加新的功能。
public class InternetFunction extends PhoneExtendFunction {public InternetFunction(IPhone phone) {super(phone);}public void internet(){System.out.println("联网功能");}@Overridepublic void function() {super.function();internet();}
}

NfcFunction.java

// 具体装饰器
// 实现抽象装饰器所增加的功能,并在调用原有方法时,增加新的功能。
public class NfcFunction extends PhoneExtendFunction{public NfcFunction(IPhone phone) {super(phone);}public void nfc(){System.out.println("NFC功能");}@Overridepublic void function() {super.function();nfc();}
}

PhotographFunction.java

// 具体装饰器
// 实现抽象装饰器所增加的功能,并在调用原有方法时,增加新的功能。
public class PhotographFunction extends PhoneExtendFunction{public PhotographFunction(IPhone phone) {super(phone);}public void photograph(){System.out.println("摄影功能");}@Overridepublic void function() {super.function();photograph();}
}

TestClient.java

public class TestClient {public static void main(String[] args) {PhotographFunction phone = new PhotographFunction(new InternetFunction(new NfcFunction(new Phone())));phone.function();}
}

执行结果:

在这里插入图片描述

装饰器模式和桥接模式的区别

装饰器模式的主要特点是在不改变现有对象结构的情况下,动态地给对象增加一些职责(功能)。装饰器是继承的有力补充,比继承更加灵活。通过使用不同的装饰类和它们的排列组合,可以实现不同的效果。在装饰器模式中,通常会有一个抽象组件和多个具体装饰器,每个装饰器都可以为对象添加新的功能,而且这些装饰器可以灵活地叠加使用。

桥接模式则是将抽象化与实现化分离,使它们可以独立变化。桥接模式包括两个继承体系:抽象部分和实现部分。抽象部分定义了一个接口,规定了实现部分需要实现的方法。实现部分则是具体的实现细节。通过这种方式,桥接模式可以减少派生类的增长,因为你可以将不同的抽象部分和实现部分进行组合,从而得到不同的功能。

两者的主要区别在于:

  • 关注点不同:装饰器模式关注于在不改变对象结构的情况下动态增加功能,而桥接模式关注于将抽象与实现分离,使它们能够独立演化。
  • 结构差异:装饰器模式是通过包装一个已存在的对象,并为其增加新的功能或行为。桥接模式则是通过抽象与实现的分离来组合不同的功能。
  • 行为的叠加性:在装饰器模式中,装饰的行为可以叠加,装饰后的对象可以拥有多个装饰器所添加的功能。而在桥接模式中,行为通常不会叠加,而是通过抽象与实现的组合来提供不同的功能。
  • 稳定性与灵活性:装饰器模式中的对象本身比较稳定,主要是为了增加新功能。而桥接模式本身可能不太稳定,因为实现部分可以独立变化。然而,这也使得桥接模式更加灵活,可以适应更多的变化和需求。

总的来说,装饰器模式和桥接模式在设计和使用上有着明显的区别。装饰器模式更注重在不改变原有结构的基础上增加新功能,而桥接模式更注重抽象与实现的分离和灵活组合

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

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

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

相关文章

echarts 多环形图

环形图效果: option {"angleAxis": {"max": 1,"show": false,"splitLine": {"show": false},"axisLabel": {"show": false},"axisTick": {"show": false}},"ra…

美国N4433A安捷伦电子校准件

181/2461/8938产品概述: 安捷伦N4433A微波电子校准(ECal)模块使矢量网络分析仪的校准变得快速、简单和准确。ECal是一种用于矢量网络分析仪的精密单连接校准技术。与机械校准套件相比,使用ECal进行完整的三端口或四端口校准所需的…

基于FPGA的HDMI设计导航页面

FPGA使用HDMI更多时候用于传输图像数据,并不会传输音频数据,因此以下文章均采用DVI接口协议,HDMI与DVI的视频传输协议基本一致,区别也很小。 首先需要了解HDMI的来源,以及物理接口类型以及引脚信号,最后对几…

【Java】Java使用Swing实现一个模拟计算器(有源码)

📝个人主页:哈__ 期待您的关注 今天翻了翻之前写的代码,发现自己之前还写了一个计算器,今天把我之前写的代码分享出来。 我记得那会儿刚学不会写,写的乱七八糟,但拿来当期末作业还是不错的哈哈。 直接上…

力扣404,左叶子之和

404. 左叶子之和 已解答 简单 相关标签 相关企业 给定二叉树的根节点 root ,返回所有左叶子之和。 示例 1: 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,…

C:数据结构之链栈(不带头)

目录 前序 准备工作 函数声明 函数接口 1.初始化 2.创造节点 3. 判断栈空 4.入栈 5.出栈 6.取栈顶元素 7.销毁栈 8. 获取栈的元素个数 总结 前序 链栈是基于单链表实现的,其实栈更加适合使用顺序表来实现的,这篇文章我们来探讨一下链栈的实现。 准备工作 老规…

透视 Insilico 英矽智能:AI 制药明星企业的飞跃、困境与破局

衰老,从古至今困扰了无数仁人志士。无论是千古一帝秦始皇,还是雄才大略汉武帝,亦或者挥斥方遒唐太宗,这些伟大的帝王无一例外的都留下了许多追求长生的故事。当时光的指针落在了 21 世纪的第二个十年,随着全球老龄化问…

【c++】string类常见接口函数

🔥个人主页:Quitecoder 🔥专栏:c笔记仓 朋友们大家好啊,本节我们来到STL内容的第一部分:string类接口函数的介绍 目录 1.string类的认识2.常见接口讲解2.1 string类对象的常见构造2.2 对string对象的遍历和…

Jackson解析Json数据

1.概述 Jackson 和 FastJson 一样,是一个 Java 语言编写的,可以进行 JSON 处理的开源工具库,Jackson 的使用非常广泛,Spring 框架默认使用 Jackson 进行 JSON 处理。 Jackson 有三个核包,分别是 Streaming、Databid、…

【实战JVM】类的生命周期

个人名片: 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻‍❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️…

百度OCR身份证识别C++离线SDKV3.0 C#对接

百度OCR身份证识别C离线SDKV3.0 C#对接 目录 说明 效果 问题 项目 代码 下载 说明 自己根据SDK封装了动态库,然后C#调用。 SDK 简介 本 SDK 适应于于 Windows 平台下的⾝份证识别系统,⽀持 C接⼜开发的 SDK,开发者可在VS2015 下⾯进⾏开发(推荐…

推荐学习什么编程语言?

选择编程语言学习时,除了就业因素外,还可以考虑以下几个方面来决定学习哪些编程语言: 个人兴趣与目标:如果你对某个特定领域感兴趣,比如游戏开发、数据分析、人工智能等,可以选择与该领域紧密相关的编程语言…

Altair® Access™ 面向研究人员和工程师的 HPC 作业提交门户

Altair Access™ 面向研究人员和工程师的 HPC 作业提交门户 Access 具有一个简单、强大且统一的界面,可以从中提交和监控远程集群、云或其他资源的相关作业,使工程师和研究人员能够专注于主要活动,减少在应用程序运行及数据移动上投入的时间。…

搭建第一个Web服务器(在eclipse或idea上部署Tomcat服务器)

💻博主现有专栏: C51单片机(STC89C516),c语言,c,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux&#xf…

2024年ERP软件上中下游结构分析及细分行业研究

环洋咨询Global Info Research的ERP软件市场调研报告提供ERP软件市场的基本概况,包括定义,分类,应用和产业链结构,同时还讨论发展政策和计划以及制造流程和成本结构,分析ERP软件市场的发展现状与未来市场趋势&#xff…

nandgame中的条件判断EQ(== 相等)、GT、LT、NOT、GOTO、IF_GOTO

相等从堆栈中弹出两个顶部值并进行比较。 如果它们相等,则推送值-1(十六进制中的FFFF)。 否则推送0。在条件语句中,FFFF代表真,0代表假。示例 之前 之后 堆栈 堆栈 7 0 8 结果如下: 代码 POP_D POP_A…

AI大模型探索之路-应用篇8:Langchain框架LangServe模块-专注于AI模型的部署

目录 前言 一、概述 二、功能特性 三、REST API 开发 四、Postman调用测试 五、Client调用测试 总结 前言 随着AI大语言模型(LLM)的技术的不断演进,AI应用的开发和部署变得越来越复杂。在这样的背景下,LangServe应运而生—…

设计模式——2_7 状态(State)

欲买桂花同载酒,终不似,少年游 ——刘过《唐多令芦叶满汀州》 文章目录 定义图纸一个例子:如何模拟一个转笔刀自动转笔刀PencilPencilSharpener 投诉和改善钝刀BladePencilSharpener 没有铅笔PencilSharpener if if ifStatePencilSharpener 碎…

48-基于腾讯云EKS的容器化部署实战

准备工作 在部署IAM应用之前,我们需要做以下准备工作: 开通腾讯云容器服务镜像仓库。安装并配置Docker。准备一个Kubernetes集群。 开通腾讯云容器服务镜像仓库 在Kubernetes集群中部署IAM应用,需要从镜像仓库下载指定的IAM镜像&#xff…

亚马逊、速卖通、lazada测评自养号与机刷有何区别?

在亚马逊平台,买家评价的重要性无需多言。许多消费者在决定购买产品前,都会习惯性地查看相关评论,对比同类产品的买家反馈,从而做出更明智的选择。正因如此,测评成为各大电商平台不可或缺的一种推广策略,亚…