赶紧收藏!2024 年最常见 20道设计模式面试题(五)

上一篇地址:赶紧收藏!2024 年最常见 20道设计模式面试题(四)-CSDN博客

九、装饰器模式是如何在不修改对象结构的情况下增加额外功能的?

装饰器模式(Decorator Pattern)是一种结构设计模式,它允许用户在不修改对象结构的情况下动态地给一个对象添加额外的职责(功能)。这种模式通过创建一个包装对象,也就是装饰者,来包裹实际对象,然后在不修改实际对象代码的前提下,提供额外的功能。

装饰器模式的组成部分:

  1. 抽象组件(Component):定义了一个接口,描述了可以动态添加的行为。
  2. 具体组件(Concrete Component):实现抽象组件接口的具体类,也就是要被装饰的具体对象。
  3. 抽象装饰者(Decorator):抽象类,实现与具体组件相同的接口,持有一个组件的实例。
  4. 具体装饰者(Concrete Decorator):实现抽象装饰者,添加额外的职责。

装饰器模式如何增加额外功能:

  1. 定义接口:首先定义一个接口,这个接口描述了对象的基本行为。

  2. 创建具体组件:实现上述接口,创建具体的对象,这些对象是将要被装饰的。

  3. 创建抽象装饰者:创建一个抽象类,实现与具体组件相同的接口,并且持有一个组件的实例。

  4. 实现具体装饰者:创建具体装饰者类,继承自抽象装饰者,实现接口中的行为,并添加额外的功能。

  5. 装饰对象:通过创建具体装饰者的实例,并将具体组件作为参数传递给装饰者,来装饰具体组件。

  6. 使用装饰者:客户端代码通过装饰者接口与装饰后的对象交互,从而获得额外的功能。

装饰器模式的优点:

  • 灵活性:可以在运行时动态地添加或修改对象的行为。
  • 扩展性:可以很容易地添加新的装饰者,而不需要修改现有代码。
  • 透明性:装饰者模式不会影响使用组件接口的客户。
  • 复用性:可以重用已有的类。

应用场景:

  • 当需要动态地给单个对象添加职责时。
  • 当需要通过一种无须修改对象结构的方式来扩展功能时。

示例:

假设我们有一个咖啡店,我们想要为咖啡添加不同的调料,而不改变咖啡本身。使用装饰器模式,我们可以这样实现:

// 抽象组件
interface Coffee {double cost();
}// 具体组件
class SimpleCoffee implements Coffee {@Overridepublic double cost() {return 10.0;}
}// 抽象装饰者
abstract class CoffeeDecorator implements Coffee {protected Coffee coffee;public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic double cost() {return coffee.cost();}
}// 具体装饰者
class MilkCoffee extends CoffeeDecorator {public MilkCoffee(Coffee coffee) {super(coffee);}@Overridepublic double cost() {return super.cost() + 2.0; // 增加牛奶的成本}
}// 客户端代码
Coffee coffee = new SimpleCoffee();
System.out.println("Cost: " + coffee.cost());Coffee milkCoffee = new MilkCoffee(coffee);
System.out.println("Cost with milk: " + milkCoffee.cost());

通过这种方式,装饰器模式允许我们透明地给对象添加新的职责,而不需要修改对象本身的代码,提供了一种灵活的扩展对象功能的方法。

十、请描述外观模式如何解决复杂系统的接口问题。

外观模式(Facade Pattern)是一种结构设计模式,它提供了一个统一的高层接口,用来访问子系统中的一群接口。外观模式定义了一个接口,这个接口使得子系统更容易使用。它隐藏了子系统内部的复杂性,让子系统与客户端之间的耦合度降低。

外观模式的组成部分:

  1. 外观(Facade):提供了一个高层的接口,使得客户端可以访问子系统中的一组功能。
  2. 子系统(Subsystem):一组类,每个类都代表了一个特定的功能,并且这些类与外观类交互。

外观模式如何解决复杂系统的接口问题:

  1. 简化接口:外观模式通过提供一个简单的接口,使得客户端不必了解子系统内部的复杂性。客户端只需要与外观类交互,而不需要直接与多个子系统类交互。

  2. 降低耦合度:通过外观类,客户端与子系统之间的耦合度降低。客户端不依赖于子系统的具体实现,只依赖于外观类。

  3. 易于扩展:当子系统需要扩展或修改时,只需要修改外观类或子系统内部的实现,而不需要修改客户端代码。

  4. 提供统一的访问点:外观类作为子系统的一个统一访问点,可以控制对子系统的操作顺序,确保操作的正确性。

  5. 隐藏实现细节:外观类隐藏了子系统的具体实现细节,客户端不需要了解子系统内部是如何工作的。

  6. 易于使用:客户端代码更加简洁和易于使用,因为它们只需要与外观类交互,而不是与多个子系统类交互。

外观模式的优点:

  • 简化客户端代码:客户端不需要了解子系统的复杂性,只需要与外观类交互。
  • 降低耦合度:客户端与子系统之间的耦合度降低,提高了系统的模块化。
  • 易于维护和扩展:子系统的修改和扩展不会影响到客户端代码。

应用场景:

  • 当需要向复杂系统的外部提供一个简化的接口时。
  • 当需要客户端与多个子系统类交互,而这些子系统类的操作顺序很重要时。

示例:

假设我们有一个计算机系统,它由多个硬件组件组成,如CPU、内存和硬盘。使用外观模式,我们可以这样实现:

// 硬件组件接口
interface Component {void turnOn();void turnOff();
}// CPU组件
class CPU implements Component {public void turnOn() { /* ... */ }public void turnOff() { /* ... */ }
}// 内存组件
class Memory implements Component {public void turnOn() { /* ... */ }public void turnOff() { /* ... */ }
}// 硬盘组件
class HardDisk implements Component {public void turnOn() { /* ... */ }public void turnOff() { /* ... */ }
}// 外观类
class ComputerFacade {private CPU cpu;private Memory memory;private HardDisk hardDisk;public ComputerFacade() {cpu = new CPU();memory = new Memory();hardDisk = new HardDisk();}public void turnOn() {cpu.turnOn();memory.turnOn();hardDisk.turnOn();}public void turnOff() {cpu.turnOff();memory.turnOff();hardDisk.turnOff();}
}// 客户端代码
ComputerFacade computer = new ComputerFacade();
computer.turnOn();
// ... 使用计算机 ...
computer.turnOff();

通过这种方式,外观模式提供了一个简化的接口来控制计算机的启动和关闭过程,隐藏了内部组件的复杂性,使得客户端代码更加简洁和易于使用。

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

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

相关文章

基于GWO-CNN-LSTM数据时间序列预测(多输入单输出)-多维时间序列模型-MATLAB实现

基于GWO-CNN-LSTM数据时间序列预测(多输入单输出)-多维时间序列模型-MATLAB实现 基于灰狼优化(Grey Wolf Optimizer, GWO)、卷积神经网络(Convolutional Neural Network, CNN)和长短期记忆网络(Long Short-Term Memor…

C# —— 对象

对象: 类的实例化,类中的其中一个, 可以访问类中的属性和方法,所以才有了对象 属性 或者对象方法 () 这种方法 创建对象: 类名 对象名 new 类名() ADC timo new ADC(); timo.name "提莫";// 给对象name 赋值 timo.age 200; // 给age 赋值 timo.sex true; // Tim…

【计算机视觉(11)】

基于Python的OpenCV基础入门——图像梯度变换 图像梯度变换Sobel算子Scharr算子Laplacian算子 图像梯度变换的代码实现以及效果图 图像梯度变换 图像梯度变换可以用于边缘检测、特征提取、增强图像和压缩图像等多种任务。图图像梯度可以把图像看成二维离散函数,图像…

什么是进程?

目录 进程 进程的特征, 概念 我们下面先简单介绍一下什么是进程 接下来看看一个程序的运行过程 进程的组成 进程的状态和转换 进程的状态 进程状态的转换 ​编辑 进程的组织方式 进程控制 如何实现进程控制 为什么进程控制的过程需要一气呵成? 进程控制的实现…

前端初学java

目录 java术语 JDK Javac Java Jdb Jhat JVM JRE JAR JDK下载 运行java文件 字面量 隐式转换 强制转换 注意 运算符 &&、||、&、| Switch 程序入口 String[] args 数组 静态初始化 动态初始化 变量初始化 Java内存 方法 重载 Final 包 …

智警杯数据库学习(1)

CentOS中安装MySQL数据库 检测系统是否自带安装 MySQL 首先检查是否自带mysql rpm -qa | grep mysql 如果有删除 rpm -e mysq 未安装,开始安装 进入software目录,解压安装包mysql5.7.25 cd /root/software tar -xvf mysql-5.7.25-1.el7.x86_64.rp…

【决战欧洲杯巅峰】欧洲杯含金量比世界杯高吗?有走地数据分析软件吗?

关于欧洲杯和世界杯的含金量对比,这是一个相当主观的问题,因为两者的价值和重要性很大程度上取决于个人的喜好和观点。但我可以从一些关键方面来为你提供比较的视角。 首先,从参赛队伍和竞技水平来看,世界杯无疑是全球范围内最具…

[渗透测试学习] SolarLab-HackTheBox

SolarLab-HackTheBox 信息搜集 nmap扫描端口 nmap -sV -v 10.10.11.16扫描结果如下 PORT STATE SERVICE VERSION 80/tcp open http nginx 1.24.0 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows n…

JAVA:Stream流式编程,解放你的生产力

一、函数式编程 函数式编程(Functional Programming,简称 FP)是一种编程范式,它强调将计算视为数学函数的评估,避免改变状态以及可变数据。与过程式编程和面向对象编程不同,函数式编程强调函数的纯洁性&…

C/S、B/S架构(详解)

一、CS、BS架构定义 CS架构(Client-Server Architecture)是一种分布式计算模型,其中客户端和服务器之间通过网络进行通信。在这种架构中,客户端负责向服务器发送请求,并接收服务器返回的响应。服务器则负责处理客户端的…

浅谈RC4

一、什么叫RC4?优点和缺点 RC4是对称密码(加密解密使用同一个密钥)算法中的流密码(一个字节一个字节的进行加密)加密算法。 优点:简单、灵活、作用范围广,速度快 缺点:安全性能较差&…

网络图用什么软件绘制

1.亿图图示 2.Microsoft Visio2019 3.CAD看图 4.Draw.io 5.processOn 引用 [1]网络绘图软件 [2]https://zhuanlan.zhihu.com/p/663733462

torchvision笔记 torchvision.ops.sigmoid_focal_loss

理论部分:机器学习笔记:focal loss-CSDN博客 torchvision.ops.sigmoid_focal_loss(inputs: Tensor, targets: Tensor, alpha: float 0.25, gamma: float 2, reduction: str none) inputs每个样本的预测值targets 与 inputs 形状相同的浮点张量 存…

Pytorch编写Transformer

本文参考自https://github.com/datawhalechina/learn-nlp-with-transformers/blob/main/docs/ 在学习了图解Transformer以后,需要用Pytorch编写Transformer,下面是写代码的过程中的总结,结构根据图解Transformer进行说明。 import numpy as …

前字节员工自爆:我原腾讯一哥们,跳槽去小公司做小领导,就签了竞业,又从小公司离职去了对手公司,结果被发现了,小公司要他赔80万

“世界那么大,我想去看看”,这句曾经火遍网络的辞职宣言,说出了多少职场人心中的渴望。然而,当我们真的迈出跳槽那一步时,才发现,现实远比想象中残酷得多。 最近,一起前字节跳动员工爆料的事件…

年终奖发放没几天,提离职领导指责我不厚道,我该怎么办?

“年终奖都发了,你还跳槽?太不厚道了吧!” “拿完年终奖就走人,这不是典型的‘骑驴找马’吗?” 每到岁末年初,关于“拿到年终奖后是否应该立即辞职”的话题总会引发热议。支持者认为,这是个人…

如何验证Rust中的字符串变量在超出作用域时自动释放内存?

讲动人的故事,写懂人的代码 在公司内部的Rust培训课上,讲师贾克强比较了 Rust、Java 和 C++ 三种编程语言在变量越过作用域时自动释放堆内存的不同特性。 Rust 通过所有权系统和借用检查,实现了内存安全和自动管理,从而避免了大部分内存泄漏。Rust 自动管理标准库中数据类…

【python实战】-- 计算所有csv文件指定数据并保存到新文件更新1

系列文章目录 文章目录 系列文章目录前言一、需求二、使用步骤1.源码 总结 前言 一、需求 判断所有指定文件是否重复,是否存在数据造假; 所有指定excel文件指定列求和,求最大值,保存到新excel 二、使用步骤 1.源码 代码如下&…

PID控制算法学习笔记分享

目录 一、参数设定 二、PID计算公式 三、位置式PID代码实现 四、增量式PID代码实现 五、两种控制算法的优缺点 六、PID算法的改进 一、参数设定 比例系数(kp):P项的作用是根据当前误差的大小来产生一个控制量。它直接与误差成正比&#…

【机器学习300问】126、词嵌入(Word Embedding)是什么意思?

人类的文字,作为一种高度抽象化的符号系统,承载着丰富而复杂的信息。为了让电脑也能像人类一样理解并处理这些文字,科学家们不断探索各种方法,以期将人类的语言转化为计算机能够理解的格式。 一、One-Hot编码的不足 在自然语言处…