金三银四面试题(二十三):装饰器模式知多少?

news2025/7/16 17:43:23

什么是装饰器模式

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许动态地向对象添加新的行为,而无需修改原始对象的结构。通过将对象包装在一个或多个装饰器对象中,装饰器模式可以增强原始对象的功能。

装饰器组件

  1. Component(组件):这是被装饰的对象的接口或抽象类。它定义了对象的行为。

  2. ConcreteComponent(具体组件):这是实现了 Component 接口的具体类。它表示要被装饰的原始对象。

  3. Decorator(装饰器):这是一个抽象类或接口,继承自 Component。它包含对 Component 对象的引用,并为原始对象提供额外的行为。

  4. ConcreteDecorator(具体装饰器):这是实现了 Decorator 的具体类。它对原始对象的行为进行增强,并在必要时调用被装饰对象的方法。

优点

  • 灵活性和可扩展性:可以在运行时动态地添加或删除装饰器,以增强对象的功能。
  • 代码复用:装饰器可以重复使用,以增加不同对象的功能。
  • 遵循开放-封闭原则:通过添加装饰器来扩展对象的行为,而不修改原始对象的结构。

举个例子

依旧是使用我们之前的咖啡的例子

// Component接口
interface Coffee {
    double cost();
    String description();
}

// ConcreteComponent
class BasicCoffee implements Coffee {
    public double cost() {
        return 2.0; // 基础咖啡的价格
    }

    public String description() {
        return "Basic Coffee"; // 基础咖啡的描述
    }
}

// Decorator抽象类
abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}

// ConcreteDecorator
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    public double cost() {
        return coffee.cost() + 0.5; // 添加牛奶的价格
    }

    public String description() {
        return coffee.description() + ", Milk"; // 添加牛奶的描述
    }
}

class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    public double cost() {
        return coffee.cost() + 0.2; // 添加糖的价格
    }

    public String description() {
        return coffee.description() + ", Sugar"; // 添加糖的描述
    }
}

// 使用装饰器模式
public class Main {
    public static void main(String[] args) {
        // 创建一个基础咖啡
        Coffee coffee = new BasicCoffee();
        
        // 添加牛奶装饰器
        coffee = new MilkDecorator(coffee);
        
        // 再次添加糖装饰器
        coffee = new SugarDecorator(coffee);
        
        // 输出咖啡的描述和价格
        System.out.println("Description: " + coffee.description());
        System.out.println("Cost: " + coffee.cost());
    }
}

我们创建了一个基础咖啡对象 BasicCoffee,然后动态地向它添加装饰器 MilkDecoratorSugarDecorator。这些装饰器增强了原始对象的功能,提供了灵活性和可扩展性。这像不像一个Class级别的建造者模式。

思考

都是对功能进行增强,那么代理模式和装饰器模式有什么区别呢?

往期推荐

金三银四面试题(二十一):代理模式知多少?2024-04-16
金三银四面试题(二十):单例模式知多少?2024-04-15
金三银四面试题(十九):MySQL中的锁2024-04-09
MySQL基础练习题:习题7-112024-04-09
金三银四面试题(十八):MySQL索引2024-04-08
MySQL基础练习题:习题4562024-04-08
金三银四面试题(十七):MySQL面试都问什么(2)2024-04-07
MySQL基础练习题:习题2-32024-04-07
MySQL基础练习题:创建数据库2024-04-07
金三银四面试题(十六):MySQL面试都问什么(1)2024-04-07

在这里插入图片描述

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

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

相关文章

Swift - 枚举

文章目录 Swift - 枚举1. 枚举的基本用法2. 关联值(Associated Values)3. 关联值举例4. 原始值5. 隐式原始值(Implicitly Assigned Raw Values)6. 递归枚举(Recursive Enumeration)7. MemoryLayout Swift -…

ESP32-C3第二路串口(非调试)串口打通(2)

接前一篇文章:ESP32-C3第二路串口(非调试)串口打通(1) 本文内容参考: ESP32爬坑之旅②——初识FreeRTOS_esp32 xtaskcreate-CSDN博客 特此致谢! 上一回讲解了ESP32-C3系列芯片UART引脚复用的细…

安卓常用组件(启停活动页面、活动之间传递信息、收发应用广播、操作后台服务)

启停活动页面 Activity的启动和结束 页面跳转可以使用startActivity接口,具体格式为startActivity(new Intent(this, 目标页面.class));。 关闭一个页面可以直接调用finish();方法即可退出页面。 Activity的生命周期 页面在安卓有个新的名字叫活动,因…

指导网友完成一起Linux服务器系统文件删除导致不能启动情况下的数据恢复案例

昨日有网友在微信群发起救助,Linux系统不能启动,使用救援U盘也无法恢复,协助他进行了数据恢复,本文记录了处置过程。 图片为网友提供,照得歪歪扭扭的,将就着看看吧。 一、问题现象 1、报错信息 Linux服…

Linux 第十一章

🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,linux 🔥座右铭:“不要等到什么都没有了…

比较美观即将跳转html源码

源码介绍 比较美观即将跳转html源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面 源码截图 比较美观的一个跳转界面,修改方法如上&…

【Spring】IOC/DI中常用的注解@Lazy、@Scope与@Conditional

目录 1、Lazy 懒加载bean 1.1、与component配合使用 1.2、与Bean注解配合使用 2、Scope bean的作用域 2.1、不指定Scope 2.2、指定Scope为 prototype 3、Conditional 条件注解 1、Lazy 懒加载bean Lazy用于指定单例bean实例化的时机,在没有指定此注解时&…

异常处理Exception(一)

文章目录 1、添加异常捕捉2、链式CATCH3、一个CTACH捕捉多个异常4、捕捉所有异常总结 有些代码可以通过语法检查,但运行时会发生错误而崩溃,比如除数是0的情况。对于这类代码,需要使用 TRY, CATCH进行异常捕捉,避免代…

ubuntu24.04 正式放弃VNC

1、ubuntu22.04支持情况 去年9月在22.04中测试发现由于gnome启用Wayland桌面,然而Wayland和vnc兼容不佳,就已经黑屏等问题,当时是vnc和ms-rd(微软远程桌面)两个菜单。 Ubuntu22.04 vnc远程黑屏_ubuntu 远程桌面vnc黑屏-CSDN博客文章浏览阅读…

FreeRTOS之列表

1.FreeRTOS的列表和列表项十分重要。列表类相当于链表,列表项则相当于链表中的节点。列表项的地址是非连续的,列表项的数量可随时修改。在OS中的任务状态和数量会发生改变,因此使用列表可以很好的满足需求。 列表和列表项的相关定义与操作函…

基于51单片机的8路抢答器—计分功能

基于51单片机的8路抢答器 (仿真+程序) 功能介绍 具体功能: 1.主持人按下复位后数码管依次显示选手的编号和分数; 2.显示结束后主持人才可以按开始按键; 3.数码管倒计时10秒,选手开始抢答&a…

Jenkins邮件发送失败问题解决

如下提示为 Extended E-mail Notification开启Debug模式下显示的错误信息, (Debug模式设置方法:Dashboard-> manage Jenkins->configure System)DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2 DEB…

Qt窗口

QMainWindow Qt 窗⼝ 是通过 QMainWindow类 来实现的。 QMainWindow 是⼀个为⽤⼾提供主窗⼝程序的类,继承⾃ QWidget 类,并且提供了⼀个预定义的 布局。QMainWindow 包含 ⼀个菜单栏(menu bar)、多个⼯具栏(tool bars)、多个浮动…

HarmonyOS NEXT应用开发之适配挖孔屏案例

介绍 本示例介绍使用屏幕属性getDefaultDisplaySync、getCutoutInfo接口实现适配挖孔屏。该场景多用于沉浸式场景下。 效果图预览 使用说明 加载完成后顶部状态栏时间和电量显示位置规避了不可用区域。 实现思路 通过setWindowLayoutFullScreen、setWindowSystemBarEnable…

自制贪吃蛇小游戏

此片文章涉及到到控制台设置的相关操作,虚拟键码,宽字符输出等,有些地方大家可能会看不懂,可以阅读以下文章来进一步了解: 控制台程序设置-CSDN博客 效果展示: QQ2024428-181932 源码已放在文章结尾 目录 …

Python | Leetcode Python题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; class Solution:def canJump(self, nums: List[int]) -> bool:n, rightmost len(nums), 0for i in range(n):if i < rightmost:rightmost max(rightmost, i nums[i])if rightmost > n - 1:return Truereturn False

AHB传输---等待传输

等待传输 slave在需要更多时间支持或采样数据时使用HREADYOUT信号插入等待状态。在等待传输期间&#xff0c;master对传输类型和地址的更改受到限制。 1. 在等待状态下传输类型的变化 当slave请求等待状态时&#xff0c;master不得更改传输类型&#xff0c;除非是以下状态&a…

Spring AOP是什么?可以拿它做什么?

Spring AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&#xff09;是Spring框架提供的一种重要特性&#xff0c;它通过在应用程序的横切关注点&#xff08;Cross-cutting Concerns&#xff09;中&#xff0c;将重复性的代码和逻辑分离出来&#xff0c;以…

青年夜校 | 李良济中医课堂,赋能“夜生活”,传承中医药文化

下班后的苏州年轻人都在干什么&#xff1f; 约饭看电影&#xff1f; 宅家打游戏&#xff1f; 最近&#xff0c;一种全新的“夜生活”模式开启啦&#xff01; 那就是—— 去家门口的夜校&#xff0c;学习中医和中药&#xff01; 1 家门口的夜校 解锁正确的中医养生法 4月…