Java特性之设计模式【装饰器模式】

一、装饰器模式

概述

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装

装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀

何时使用:在不想增加很多子类的情况下扩展类

优缺点

优点:

  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能

缺点:

  • 多层装饰比较复杂

1. 各个角色介绍

1.1 抽象组件(Component)

  • 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等

1.2 具体组件(Concrete Component)

  • 是被装饰的原始对象,它定义了需要添加新功能的对象

1.3 抽象装饰器(Decorator)

  • 继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象

1.4 具体装饰器(Concrete Decorator)

  • 实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作

2. UML图

​ 将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。RedShapeDecorator 是实现了 ShapeDecorator 的实体类

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Shape:形状接口

    • Rectangle:实现形状接口的长方形类
    • Circle:实现形状接口的圆形类
  • ShapeDecorator:形状装饰器抽象类

    • RedShapeDecorator:红色形状装饰器(继承ShapeDecorator)

3.1 抽象组件及其实现类

  • Shape
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 形状接口* @since 2024/3/15 16:23*/
public interface Shape {/*** 形状绘制动作*/void draw();}
  • Rectangle
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 长方形* @since 2024/3/15 16:26*/
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Rectangle");}}
  • Circle
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 圆形* @since 2024/3/15 16:28*/
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Circle");}}

3.2 抽象装饰器及其具体装饰器

  • ShapeDecorator
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 形状装饰器* @since 2024/3/15 16:30*/
public abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape) {this.decoratedShape = decoratedShape;}public void draw() {decoratedShape.draw();}}
  • RedShapeDecorator
package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 红色形状装饰器* @since 2024/3/15 16:32*/
public class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape) {System.out.println("Border Color: Red");}}

3.3 测试主函数

package com.vinjcent.prototype.decorator;/*** @author vinjcent* @description 装饰器模式* @since 2024/3/15 16:39*/
public class Main {public static void main(String[] args) {Shape circle = new Circle();// ShapeDecorator redCircle = new RedShapeDecorator(new Circle());// ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());Shape redCircle = new RedShapeDecorator(new Circle());Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Circle with normal border");circle.draw();System.out.println("\nCircle of red border");redCircle.draw();System.out.println("\nRectangle of red border");redRectangle.draw();}}
  • 测试结果

在这里插入图片描述

4. 使用场景

  • 动态增强功能:使用装饰器模式可在运行时为对象灵活地增加额外功能。通过组合各种装饰器,能够实现不同功能的组合,而无需改变原始对象的代码
  • 避免继承的功能扩展:当使用继承来增强对象功能时会导致类的层次结构过于复杂时,考虑采用装饰器模式。通过组合而非继承来实现功能扩展,避免了深层次和复杂的类继承结构
  • 维护对象的封装性:若需为对象添加功能,同时又不愿修改原始对象的代码或破坏其封装性,可采用装饰器模式。该模式不改变原对象结构,只是在其上方增添功能
  • 弹性组合多项功能:若需为对象添加多项功能,且这些功能可弹性组合,则可采用装饰器模式。透过组合各种装饰器,能够实现各种功能的组合,而无需创建大量子类
  • 贯彻单一职责原则:在需要将功能添加与原始对象实现分离,以符合单一职责原则时,可采用装饰器模式。每个装饰器类专注于一个特定功能,这有助于使类的职责更加明确

在这里插入图片描述

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

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

相关文章

cocos 3.8开发 微信小游戏分包技巧压缩主包

Creator 版本: 3.8.2 目标平台:小游戏开发 压缩后 我不知道别人压缩几百kb是怎么做到的。不过哪个要钱。 我这个技巧不用花钱。 论坛有教程但是没有教详细怎么做。 开整! 做一个空白的场景。然后写一个load脚本。load主场景。 从代码可…

归并算法详细解析

归并排序 1945年,约翰冯诺依曼(John von Neumann)发明了归并排序,这是典型的分治算法的应用。归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Di…

数据结构:堆

堆的概念 1.堆是一个完全二叉树 2.小堆(任何一个父亲<孩子),大堆(任何一个父亲>孩子) 堆的结构 物理结构:数组 逻辑结构:二叉树 #pragma once #include<assert.h> #include<iostream> typedef int HPDataType; typedef struct Heap {HPDataType* _a;int…

数据挖掘之关联规则

“啤酒和尿布的荣誉” 概念 项 item&#xff1a;单个的事物个体 &#xff0c;I{i1,i2…im}是所有项的集合&#xff0c;|I|m是项的总数项集&#xff08;item set)/模式&#xff08;pattern)&#xff1a;项的集合&#xff0c;包含k个项的项集称为k-项集数据集(data set)/数据库…

Redis设计原理简介

键值存储模型&#xff1a; Redis是一个基于内存的键值对存储系统&#xff0c;它支持五种基本数据结构&#xff08;字符串String、哈希Hash、列表List、集合Set、有序集合Sorted Set&#xff09;以及几种高级数据结构如Bitmaps、HyperLogLogs等。 单线程架构&#xff1a; Redis采…

php 对接IronSource海外广告平台收益接口Reporting API

今天对接的是IronSource广告reporting api接口&#xff0c;拉取广告收益回来自己做统计。记录分享给大家 首先是文档地址,进入到IronSource后台就能看到文档地址以及参数&#xff1a; 文档地址&#xff1a;https://developers.is.com/ironsource-mobile/air/reporting/ 在这里插…

管理类联考–复试–英文面试–问题–WhatWhyHow--纯英文汇总版

文章目录 Do you have any hobbies? What are you interested in? What do you usually do in your spare time? Could you tell me something about your family&#xff1f; Could you briefly introduce your family? What is your hometown like? Please tell me so…

ab (Apache benchmark) - 压力/性能测试工具

Apache benchmark&#xff08;ab&#xff09; 安装window安装使用方法 - bin目录运行使用方法 - 任意目录运行 linux安装 基本命令介绍常用参数:输出结果分析&#xff1a; ab的man手册 安装 window安装 官网下载链接&#xff1a;https://www.apachehaus.com/cgi-bin/download…

【LinuxC】C语言线程(pthread)

文章目录 一、 POSIX 线程库1.1 POSIX标准1.2 Pthreads1.2 数据类型、函数、宏1.21 数据类型1.22 函数1.23 宏 二、创建线程三、线程同步四、线程销毁五、示例5.1 完整示例5.2 信号量示例 本专栏上一篇文章是Windows下&#xff08;MSVC&#xff09;的线程编程&#xff0c;需要的…

[实践经验]: visual studio code 实用技巧

目录 editor rulers 这里主要总结一些常用的VScode技巧&#xff0c;不定时更新… editor rulers 设置 -> 搜索 editor.rulers -> edit in settings.json "editor.rulers": [{"column": 80,"color": "#ff00FF"},]效果如图

Linux:设置别名命令alias

相关阅读 Linuxhttps://blog.csdn.net/weixin_45791458/category_12234591.html?spm1001.2014.3001.5482 在Linux中alias命令用于为一串字符&#xff08;常代表命令&#xff09;设置一个别名&#xff0c;该别名在Bash读取并解析一行命令时会被展开。 下面是该命令的语法与选项…

python(django)之产品后台管理功能实现

1、添加新项目 在命令行输入以下代码 python manage.py startapp prroduct 2、添加路径和代码结构 在新项目目录下admin.py中加入以代码 from .models import Product class ProductAdmin(admin.ModelAdmin):list_display [product_name, product_desc,producter,created_…

牛客小白月赛86(D剪纸游戏)

题目链接:D-剪纸游戏_牛客小白月赛86 (nowcoder.com) 题目描述: 输入描述: 输入第一行包含两个空格分隔的整数分别代表 n 和 m。 接下来输入 n行&#xff0c;每行包含 m 个字符&#xff0c;代表残缺纸张。 保证&#xff1a; 1≤n,m≤10001 字符仅有 . 和 * 两种字符&#xf…

利用autodl服务器跑模型

1. 租用服务器 本地改模型 服务器 将改进好的、数据集处理好的模型压缩为zip文件上传到阿里云盘打开服务器AUTODL服务器&#xff0c;在主页中选择容器实例 在此位置进行开关机操作&#xff0c;若停止服务器&#xff0c;必须关机&#xff0c;不然会一直扣钱 2. 运行模型 选择…

Nacos详解,从安装到服务部署,及nginx反向代理

Nacos 安装 Windows安装 下载 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; GitHub主页&#xff1a;https://github.com/alibaba/nacos GitHub的Release下载页&#xff1a;https://github.com/alibaba/nacos…

peft模型微调_IA3

IA3&#xff08;论文&#xff1a;Few-Shot Parameter-Efficient Fine-Tuning is Better and Cheaper than In-Context Learning&#xff09;&#xff0c;通过学习向量来对激活层加权进行缩放&#xff0c;从而获得更强的性能&#xff0c;同时仅引入相对少量的新参数&#xff0c;…

鸿蒙:@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化

在实际应用开发中&#xff0c;应用会根据开发需要&#xff0c;封装自己的数据模型。对于多层嵌套的情况&#xff0c;比如二维数组&#xff0c;或者数组项class&#xff0c;或者class的属性是class&#xff0c;他们的第二层的属性变化是无法观察到的。这就引出了Observed/Object…

【文末附gpt升级4.0方案】FastGPT详解

FastGPT知识库结构讲解 FastGPT是一个基于GPT模型的知识库&#xff0c;它的结构可以分为以下几个部分&#xff1a; 1. 数据收集&#xff1a;FastGPT的知识库是通过从互联网上收集大量的文本数据来构建的。这些数据可以包括维基百科、新闻文章、论坛帖子等各种类型的文本。 2…

转置卷积(transposed-conv)

一、什么是转置卷积 1、转置卷积的背景 通常&#xff0c;对图像进行多次卷积运算后&#xff0c;特征图的尺寸会不断缩小。而对于某些特定任务 (如图像分割和图像生成等)&#xff0c;需将图像恢复到原尺寸再操作。这个将图像由小分辨率映射到大分辨率的尺寸恢复操作&#xff0c…

聚类算法( clustering algorithm):

在前两章&#xff0c;我们学的是&#xff1a;线性回归&#xff0c;逻辑回归&#xff0c;深度学习(神经网络)&#xff0c;决策树&#xff0c;随即森林算法。他们都是监督学习的例子。 在这一章里&#xff0c;我们将学习非监督学习的算法。 什么是聚类算法&#xff1a; 聚类算…