赶紧收藏!2024 年最常见 20道设计模式面试题(二)
上一篇地址:赶紧收藏!2024 年最常见 20道设计模式面试题(一)-CSDN博客
三、解释抽象工厂模式,并给出一个实际应用的例子。
抽象工厂模式是一种创建型设计模式,用于创建一系列相关或依赖对象的接口,而无需指定它们具体的类。这种模式通常用于当需要生成一组对象时,这些对象具有共同的抽象特性,但是具体实现可能因情况而异。
抽象工厂模式的特点:
- 抽象化:定义了一个创建对象的接口,允许通过子类来生成具体对象。
- 封装性:客户端不需要知道具体的类是如何实现的,只需要知道它们遵循相同的接口。
- 灵活性:可以独立于具体类的变化而变化,易于扩展新的产品族。
- 解耦:将类的实例化延迟到子类中进行。
抽象工厂模式的结构:
- 抽象工厂(Abstract Factory):声明了一组创建对象的方法,每个方法对应一种产品。
- 具体工厂(Concrete Factory):实现抽象工厂的接口,生成一组具体产品。
- 抽象产品(Abstract Product):定义了产品的接口。
- 具体产品(Concrete Product):实现了抽象产品的接口,由具体工厂创建。
抽象工厂模式的实现步骤:
- 定义抽象产品类和接口。
- 定义具体产品类,实现抽象产品接口。
- 定义抽象工厂类,提供创建抽象产品的接口。
- 定义具体工厂类,实现抽象工厂的接口,生成具体产品。
抽象工厂模式的示例(Java语言):
// 抽象产品A
interface ProductA {void doSomething();
}// 具体产品A1
class ConcreteProductA1 implements ProductA {public void doSomething() {System.out.println("具体产品A1的doSomething方法");}
}// 抽象产品B
interface ProductB {void doSomething();
}// 具体产品B1
class ConcreteProductB1 implements ProductB {public void doSomething() {System.out.println("具体产品B1的doSomething方法");}
}// 抽象工厂
interface Factory {ProductA createProductA();ProductB createProductB();
}// 具体工厂1
class ConcreteFactory1 implements Factory {public ProductA createProductA() {return new ConcreteProductA1();}public ProductB createProductB() {return new ConcreteProductB1();}
}
使用场景:
抽象工厂模式的一个实际应用例子是GUI工具包。假设你正在开发一个应用程序,需要支持多种不同的GUI工具包,例如Windows风格和Mac风格。每种风格都有自己的按钮、文本框等控件。
// GUI组件的抽象产品
interface Button {void paint();
}interface TextBox {void paint();
}// Windows风格的具体产品
class WindowsButton implements Button {public void paint() {System.out.println("绘制Windows风格的按钮");}
}class WindowsTextBox implements TextBox {public void paint() {System.out.println("绘制Windows风格的文本框");}
}// Mac风格的具体产品
class MacButton implements Button {public void paint() {System.out.println("绘制Mac风格的按钮");}
}class MacTextBox implements TextBox {public void paint() {System.out.println("绘制Mac风格的文本框");}
}// 抽象工厂
interface GUIFactory {Button createButton();TextBox createTextBox();
}// Windows风格的具体工厂
class WindowsFactory implements GUIFactory {public Button createButton() {return new WindowsButton();}public TextBox createTextBox() {return new WindowsTextBox();}
}// Mac风格的具体工厂
class MacFactory implements GUIFactory {public Button createButton() {return new MacButton();}public TextBox createTextBox() {return new MacTextBox();}
}
在这个例子中,GUIFactory是一个抽象工厂,用于创建GUI组件。WindowsFactory和MacFactory是具体工厂,分别生成Windows和Mac风格的GUI组件。应用程序可以根据用户的选择或系统环境来使用不同的工厂,从而生成相应风格的GUI组件。这样,应用程序的GUI就可以很容易地适应不同的操作系统风格,而不需要修改大量的代码。
四、建造者模式是如何解决复杂对象构建问题的?
建造者模式(Builder Pattern)是一种创建型设计模式,用于解决复杂对象的构建问题。它允许通过逐步构建一个复杂对象来分离对象的构建过程和表示,使得同一个构建过程可以创建不同的表示。
建造者模式的特点:
- 分离构建与表示:将对象的构建过程从其表示中分离出来,使得相同的构建过程可以创建不同的表示。
- 灵活性:可以控制复杂对象的构建过程,允许逐步构建对象,并且可以在构建过程中修改构建步骤。
- 可扩展性:当需要添加新的产品属性或构造方法时,不需要修改现有的构建类,只需要添加新的建造者类即可。
- 减少复杂性:避免了使用大量的可选参数,这些参数可能会使构造函数变得复杂且难以管理。
建造者模式的结构:
- 产品(Product):需要构建的复杂对象。
- 建造者(Builder):创建产品的接口,定义了一系列的设置方法,用于设置产品的不同部分。
- 具体建造者(Concrete Builder):实现建造者接口,具体实现构建产品的方法。
- 指挥者(Director):负责使用建造者来构建产品的过程,它不依赖于具体建造者的具体实现。
建造者模式的实现步骤:
- 定义产品类,包含多个属性和构造这些属性的方法。
- 定义建造者接口,包含设置产品属性的方法和一个返回产品实例的方法。
- 实现具体建造者类,实现建造者接口,并构建最终的产品实例。
- 定义指挥者类,包含一个方法,接受一个建造者对象,并使用它来构建产品。
建造者模式的示例(Java语言):
// 产品类
class Product {private String part1;private String part2;public void setPart1(String part1) {this.part1 = part1;}public void setPart2(String part2) {this.part2 = part2;}@Overridepublic String toString() {return "Product{" +"part1='" + part1 + '\'' +", part2='" + part2 + '\'' +'}';}
}// 建造者接口
interface Builder {void setPart1(String part1);void setPart2(String part2);Product build();
}// 具体建造者
class ConcreteBuilder implements Builder {private Product product = new Product();public void setPart1(String part1) {product.setPart1(part1);}public void setPart2(String part2) {product.setPart2(part2);}public Product build() {return product;}
}// 指挥者
class Director {public Product construct(Builder builder) {builder.setPart1("Part1");builder.setPart2("Part2");return builder.build();}
}
使用场景:
建造者模式非常适合于以下场景:
- 当创建复杂对象的算法应该独立于对象本身的表示时。
- 当需要创建一个复杂对象的不同变体时。
- 当希望对象的创建过程与使用过程分离时。
例如,假设你正在构建一个汽车配置系统,汽车可能有不同的引擎、轮胎、颜色等配置选项。使用建造者模式,你可以定义一个汽车建造者接口,然后为每种配置实现一个具体的建造者类。指挥者类可以根据不同的需求调用不同的建造者来构建具有特定配置的汽车实例。
通过这种方式,建造者模式提供了一种灵活且可扩展的方式来构建复杂的对象,同时保持了代码的清晰和易于管理。
相关文章:
赶紧收藏!2024 年最常见 20道设计模式面试题(二)
上一篇地址:赶紧收藏!2024 年最常见 20道设计模式面试题(一)-CSDN博客 三、解释抽象工厂模式,并给出一个实际应用的例子。 抽象工厂模式是一种创建型设计模式,用于创建一系列相关或依赖对象的接口&#x…...
Java面向对象设计 - Java泛型约束
Java面向对象设计 - Java泛型约束 无限通配符 通配符类型由问号表示,如<?> 。 对于通用类型,通配符类型是对象类型用于原始类型。 我们可以将任何已知类型的泛型分配为通配符类型。 这里是示例代码: // MyBag of String type M…...
什么是内存泄漏?如何避免内存泄漏?
**内存泄漏(Memory Leak)**是指在程序运行过程中,已经动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏具有隐蔽性、积累性的特征&#x…...
元组(tuple)(Python)
文章目录 一、定义二、常用操作 一、定义 tuple ("张三", "李四", "王二")二、常用操作 分类关键字/函数/方法说明查询元组[索引]根据索引取值,索引不存在会报错len(元组)元组长度(元素个数)值 in 元组&…...
【C++进阶学习】第二弹——继承(下)——挖掘继承深处的奥秘
继承(上):【C进阶学习】第一弹——继承(上)——探索代码复用的乐趣-CSDN博客 前言: 在前面我们已经讲了继承的基础知识,让大家了解了一下继承是什么,但那些都不是重点,今…...
LangChain-ChatGLM本地搭建|报错合集(win10)
安装过程 1. 创建虚拟环境 conda create -n langchain-chatglm python3.10 conda activate langchain-chatglm2. 部署 langchain-ChatGLM git clone https://github.com/imClumsyPanda/langchain-ChatGLMpip3 install -r requirements.txt pip3 install -U gradio pip3 inst…...
IP地址简介
一、IP地址 Internet Protocol Address,即网络层协议地址,是IP的缩写。 二、IP地址的作用 为什么不直接使用MAC,又加了一个IP地址呢? 事实上底层传输,最终使用的肯定是MAC地址,但是由于在以前&#x…...
谈吐的艺术
被人表扬,该怎么回应 你越是说自己其实没那么好, 对方出于客气, 就越是要证明你其实比你说的好得多。 O可能遇到的问题 每当工作和学习上做出点成绩,有人夸奖我的时候,我都会觉得很尴尬。因为不谦虚会得罪人ÿ…...
Linux 和 分区
文章目录 流程挂载设备文件名 Linux 下各分区的含义家目录 流程 在windows中,一个硬盘要使用只需要分区、格式化之后就可以使用了 在linux中,除了分区和格式化之外,还需要一个叫挂载的操作 挂载 挂载,就相当于windows环境下的写…...
⭐ ▶《强化学习的数学原理》(2024春)_西湖大学赵世钰 Ch3 贝尔曼最优公式 【压缩映射定理】
PPT 截取必要信息。 课程网站做习题。总体 MOOC 过一遍 1、视频 学堂在线 习题 2、过 电子书,补充 【下载:本章 PDF 电子书 GitHub 界面链接】 [又看了一遍视频] 3、总体 MOOC 过一遍 习题 学堂在线 课程页面链接 中国大学MOOC 课程页面链接 B 站 视频链…...
Pikachu上的CSRF以及NSSCTF上的[NISACTF 2022]bingdundun~、 [SWPUCTF 2022 新生赛]xff
目录 一、CSRF CSRF(get) login CSRF(post) CSRF Token 二、CSRF的相关知识点 (1)什么是CSRF? (2)工作原理 (3)CSRF漏洞形成的条件 1、用户要在登录状态(即浏览器保存了该…...
大数据分析-二手车用户数据可视化分析
项目背景 在当今的大数据时代,数据可视化扮演着至关重要的角色。随着信息的爆炸式增长,我们面临着前所未有的数据挑战。这些数据可能来自社交媒体、商业交易、科学研究、医疗记录等各个领域,它们庞大而复杂,难以通过传统的数据处…...
AI训练Checkpoint对存储的影响
检查点(Checkpoints)是机器学习和深度学习训练过程中的一个重要机制,旨在定期保存训练状态,以便在训练过程中遇到失败或中断时能够从中断处恢复训练,而无需从头开始。 随着模型参数量的剧增,Checkpoint文件…...
Python笔记 - 正则表达式
正则表达式(Regular Expression,简称regex)是一种强大的工具,用于匹配字符串模式。在Python中,正则表达式通过re模块提供。本文将带你深入了解Python中的正则表达式,从基础概念到高级用法。 1. 什么是正则…...
安卓网络通信(多线程、HTTP访问、图片加载、即时通信)
本章介绍App开发常用的以下网络通信技术,主要包括:如何以官方推荐的方式使用多线程技术,如何通过okhttp实现常见的HTTP接口访问操作,如何使用Dlide框架加载网络图片,如何分别运用SocketIO和WebSocket实现及时通信功能等…...
Virtual Memory Primitives for User Program翻译
Virtual Memory Primitives for User Program 安德鲁阿普尔(Andrew Appel)和李凯(Kai Li) 普林斯顿大学计算机科学系 摘要 传统上,内存管理单元(MMUS)被操作系统用于实现磁盘分页的虚拟内存…...
网络基础2
目录 应用层HTTP协议认识URLurlencode和urldecode HTTP协议格式http请求格式http响应格式 HTTP的方法GET与POST的区别 HTTP的状态码HTTP常见HeaderCookie与Session 传输层在谈端口号端口号范围划分认识知名端口号netstatpidof UDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲…...
C# 下载文件2
从服务下载压缩包 过程 发起请求 HttpWebRequest 断点续传 HttpWebRequest.AddRange() 获取服务资源的响应 HttpWebResponse 设置下载进度条 解压压缩包 ZipFile using System; using System.IO; using System.IO.Compression; using System.Net;namespace Test01 {clas…...
Unity | Tilemap系统
目录 一、准备工作 1.插件导入 2.资源导入 二、相关组件介绍 1.Grid组件 2.Tilemap组件 3.Tile 4.Tile Palette 5.Brushes 三、动态创建地图 四、其他功能 1.移动网格上物体 2.拖拽缩放地图 Unity Tilemap系统为2D游戏开发提供了一个直观且功能强大的平台ÿ…...
CSS选择符和可继承属性
属性选择符: 示例:a[target"_blank"] { text-decoration: none; }(选择所有target"_blank"的<a>元素) /* 选择所有具有class属性的h1元素 */ h1[class] { color: silver; } /* 选择所有具有hre…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
