Java 装饰器模式(Decorator) - krt

news/2025/10/13 22:32:48/文章来源:https://www.cnblogs.com/wwqkrt/p/19012567

装饰器模式

  装饰器模式属于结构型设计模式。它允许向一个现有的对象添加新的功能,同时又不改变其结构。

  例如:给一个普通的杯子加上杯盖、杯套,让它具有保温防烫等功能,而杯子本身的基本结构并没有发生变化。在软件开发过程中,当我们需要在运行时动态的为对象添加职责,并且避免通过继承来扩展功能带来的类层次结构复杂问题时,装饰器模式就派上用场了。

  装饰器模式主要包含以下几个角色:

  1.抽象组件(component):定义一个抽象接口,规范具体组件和装饰器的行为

  2.具体组件(concrete component):实现抽象组件接口,是被装饰的具体对象

  3.抽象装饰器(decorator):继承或实现抽象组件接口,持有一个抽象组件的引用,并定义一个可以动态添加职责的方法

  4.具体装饰器(concrete decorator):实现抽象装饰器接口,负责为具体组件添加具体功能

核心思想

  1.动态扩展:在运行时添加/删除功能,而非编译时

  2.组合优于继承:通过对象组合实现功能叠加,避免类爆炸

  3.透明性:装饰后的对象与原对象接口一致,对客户端透明

典型使用场景

  1.I/O流操作(Java原生)如InputStream、BufferedInputStream、DataInputStream等,都是典型的装饰器模式应用
  2.权限控制/日志记录等通用功能增强,在不改变核心业务逻辑的前提下,为服务添加日志、缓存、安全等功能。

  3.UI组件扩展,比如按钮组件加上边框、阴影、滚动等效果

  4.Spring的AOP(面向切面编程)Spring使用了类似装饰器的思想来实现方法拦截和增强。

image

 

装饰器模式实现步骤

1.故事背景:机器人功能扩展的两种方案

在智能家居领域,某科技公司推出了第一代家用机器人,它具备三个核心功能:对话、唱歌和播放音乐。

image

// 第一代机器人:基础功能
interface Robot {void talk();    // 对话void sing();    // 唱歌void playMusic(); // 播放音乐
}class FirstGenerationRobot implements Robot {@Overridepublic void talk() {System.out.println("机器人:你好,我能陪你聊天");}@Overridepublic void sing() {System.out.println("机器人:正在播放《青花瓷》");}@Overridepublic void playMusic() {System.out.println("机器人:正在播放轻音乐");}
}

 

 随着用户需求升级,厂家希望扩展机器人的功能,让它能够扫地和跳舞。针对这个需求,有两种技术方案可供选择:

image

 

⑴.方案一:传统继承(厂家升级方案)

  厂家选择开发第二代机器人,通过继承第一代产品并添加新功能:

    接口定义
// 基础接口:第一代机器人支持的功能
interface Robot {void talk();void sing();void playMusic();
}

 

 
  类实现
// 第一代机器人(基础实现)
class FirstGenerationRobot implements Robot {@Overridepublic void talk() {System.out.println("对话中...");}@Overridepublic void sing() {System.out.println("正在唱歌...");}@Overridepublic void playMusic() {System.out.println("播放音乐中...");}
}// 第二代机器人:通过继承方式扩展功能
class SecondGenerationRobot extends FirstGenerationRobot {public void sweep() {System.out.println("正在扫地...");}public void dance() {System.out.println("正在跳舞...");}
}

 

测试代码

public class InheritanceTest {public static void main(String[] args) {System.out.println("=== 继承方式测试 ===");SecondGenerationRobot robot = new SecondGenerationRobot();robot.talk();robot.sing();robot.playMusic();robot.sweep();  // 扩展功能robot.dance();   // 扩展功能
    }
}

⑵.方案二:装饰器模式

image

 

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

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

相关文章

Python configparser 模块 - INI 文件读写利器

知识预热 什么是 configparser? configparser 是 Python 标准库中用于读写 INI 格式配置文件 的模块。 它提供了一种 简单、直观、跨平台 的方式来管理程序的配置项。什么是 INI 文件? .ini 文件是 Initialization F…

AlexNet vs LeNet 对比实验

1. AlexNet 论文的关键创新点 (2012, ImageNet Classification with Deep Convolutional Neural Networks)创新点 简述 意义ReLU 激活函数 用 ReLU 替代 Sigmoid/Tanh 缓解梯度消失,训练速度更快Dropout 正则化 全连接…

OpenHarmony中的环境服务管理配置讲解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

QT:获取文件信息之创建日期方法created()方法--废弃

QT:获取文件信息之创建日期方法created()方法--废弃。 在Qt5.12框架中,QFileInfo::created()方法已被标记为废弃(deprecated),建议使用birthTime()或metadataChangeTime()替代。fileinfo.cpp:90:30: warning: create…

排列组合 容斥 总结

加法原理 加法原理。很直白的,就是一个用加法来弄的原理。 简单来说,就是做一件事情有 \(n\) 种方法,第 \(i\) 种方法又有 \(a_i\) 个具体的操作方案。那么非常显然,做这件事情就有 \(a_1 + a_2 + \dots + a_{n-1}…

10.13每日总结

今天满课,软件设计+软件开发案例分析+大数据技术+物联网工程,很忙,且开始看中级软件工程师的网课了,,,看起来真的很难,不是我擅长的那一挂,周末外语竞赛的成绩就出来了,,加油!

完整教程:学习 React 前掌握 JavaScript 核心概念

完整教程:学习 React 前掌握 JavaScript 核心概念pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

新学期每日总结(第7天)

今日相较昨日 学习了类与对象

20232422 2025-2026-1 《网络与系统攻防技术》实验一实验报告

实验目的 掌握ELF可执行文件的机器指令修改方法,理解程序执行流控制原理; 理解缓冲区溢出(BOF)漏洞的原理,掌握通过覆盖返回地址改变程序执行流的攻击方法; 学会构造并注入shellcode,理解漏洞利用的完整流程; …

详细介绍:redis特性和应用场景

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

实验记录 2025/10/13

2025/10/13 使用配置:yolo11s.yaml from ultralytics import YOLOdef main():# 1. 并非加载预训练模型(这里用 YOLO11n,也可以换成 yolov11s、best.pt 等)# 而是让YAML 定义自己的网络结构model = YOLO(model=r…

newDay09

1.今天课程比较多,晚上简单复习了面向对象的知识,背背单词 2.明天还是再补补java吧 3.感觉自己基础还是太薄弱了,课堂上很多问题答不出来

正睿25csp七连测day5

题面:这场打得很飞舞,\(40pts,rk54\)。 T1 这道题比较考验思维。 我们可以考虑每个点是从最初序列的哪个位置转移过来了(记为 \(from\))。 不难发现,如果最终序列中的几个位置的 \(from\) 相等,那么这几个位置代…

C/C++ 指针详解与各种指针定义 - 指南

C/C++ 指针详解与各种指针定义 - 指南2025-10-13 22:09 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !i…

14 10.13

上了数据结构 统一建模语言 Java跑步了背了单词

日志|前端框架Vue

Vue是一款用于构建用户界面的渐进式的JavaScript框架1)2)3)v-bindv-onv-if v-else-if v-else = v-showv-forv-实例演示vue生命周期的挂载完成提示

oop.shiyan1

实验1 源代码:1 #include<iostream>2 #include<string>3 #include<vector>4 #include<algorithm>5 6 //模版函数声明7 template<typename T>8 void output(const T& c);9 10 void …

玄机——第一章 应急响应-Linux日志分析 wp

简介 账号root密码linuxrz ssh root@IP 1.有多少IP在爆破主机ssh的root帐号,如果有多个使用","分割 2.ssh爆破成功登陆的IP是多少,如果有多个使用","分割 3.爆破用户名字典是什么?如果有多个使…