探索设计模式的魅力:创建型设计模式的比较与决策


设计模式专栏:http://t.csdnimg.cn/U54zu


目录

一、设计模式概览

1.1 创建型模式

二、比较创建型设计模式

1.1 适用场景典型用例

1.2 关键要素与差异对比

1.3 结构图

三、模式选择指南

3.1 场景分析

3.2 决策流程图

四、结语

4.1 优势

4.2 考量因素


一、设计模式概览

    在软件工程中,设计模式是一套经过精心挑选的通用、可重复使用的解决特定设计问题的模板。它们是在多年软件开发实践中总结出来的最佳实践的集合,用于解决面向对象设计中常见的问题。设计模式可以加速软件开发过程,提高开发效率并促进团队之间的沟通。

    设计模式分类通常分为三大类:

 1. 创建型模式 (Creational Patterns)
 2. 结构型模式 (Structural Patterns)
 3. 行为型模式 (Behavioral Patterns)

1.1 创建型模式

    创建型设计模式关注对象创建的机制,尤其是当一个系统需要独立于其构成的类的实例化方式时。创建型模式的核心思想是将对象的创建和使用分离,以提供更大的系统灵活性。这类模式通常在涉及以下场景时会特别有用:

 1. 当系统需要独立于它的产品的创建、组合和表示时。
 2. 当需要封装一个类的实例化过程时。
 3. 当提供对象创建的多个变体,但不想暴露创建逻辑的细节时。

    创建型模式不仅可以隐藏这些实例化细节,还能通过定义创建接口将、系统中的对象创建与系统的其他部分解耦。这为改变系统内或系统间的对象创建过程提供了灵活性,可以改进代码的模块性、可扩展性和维护性。

        

    常见的创建型模式包括单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式(Prototype)。每种模式解决了特定的问题,但它们的共同之处在于使得系统不必关心对象具体如何被创建、组成和表示。

        

    在如今快速变化的软件设计领域,理解和运用创建型模式越来越成为了软件架构师和开发人员的基础技能。通过使用这些模式,开发人员可以更加集中精力在业务逻辑上,而不必过分关注对象创建的复杂性,从而加快开发进度并降低后期的维护成本。

        

    在下一部分中,我们将深入探讨各种创建型模式,了解它们是如何工作的,以及它们在实际应用中如何能够为我们带来架构上的好处。

        

二、比较创建型设计模式

1.1 适用场景典型用例

 1. 单例模式:http://t.csdnimg.cn/gRd4l

  • 当一个类只需要一个实例,并且需要一个全局访问点时,单例模式就非常有用。例如,数据库连接池或日志记录工具通常就是单例。
  • 当系统中只需要一个实例对象,或者需要一个全局访问点来访问某个资源时,可以使用单例模式。例如,配置信息的读取、线程池、缓存管理等。

 2. 简单工厂:http://t.csdnimg.cn/7mLkH

  • 当需要创建的对象不多,且整个系统的设计不复杂时候。简单工厂能够根据传入参数返回多个可能类中的一个实例。
  • 适用于根据传入的参数创建不同类型对象,但不需要知道具体创建细节的场景。例如,根据配置信息创建不同类型的数据库连接对象。

 3. 工厂方法:http://t.csdnimg.cn/ldsMK

  • 与简单工厂相比,当对象的创建逻辑较复杂或对象的类型较多时,每个具体产品的创建都有自己的逻辑时适用工厂方法模式。例如,不同类型的数据库连接工厂或不同风格的UI组件工厂。
  • 适用于系统中有多个具体产品类,并且它们的创建逻辑可能有所不同,但客户端只需要关心接口的场景。例如,不同类型的图形绘制对象创建。

 4. 抽象工厂:http://t.csdnimg.cn/X7iwq

  • 适用于有多种产品族,而系统只消费其中某一系列产品的场景。比如跨平台UI工具箱,需要根据不同操作系统生成不同UI控件。
  • 当需要创建一系列相互关联或依赖的对象时,并且这些对象家族中的对象具有相同的约束条件时,可以使用抽象工厂模式。例如,创建不同主题的皮肤或界面。

 5. 建造者模式:http://t.csdnimg.cn/zUj9V

  • 当需要创建的对象非常复杂,有多个组成部分且这些部分的构建顺序可能不同,也可能需要不同的构建过程时,建造者模式是合适的。例如创建一个复杂的文档或UI布局。
  • 当需要构建的对象具有复杂的内部结构,并且这些对象的构建过程与表示过程相互分离时,可以使用建造者模式。例如,构建具有多个可选配置的复杂对象,如电脑配置、房屋装修等。

 6. 原型模式:http://t.csdnimg.cn/mORjg

  • 适用于创建新对象成本较高时,通过复制现有对象并修改为所需状态更为有效时。如当需要复制或克隆复杂的配置对象。
  • 当需要频繁创建相似对象,并且创建对象的成本较高时,可以使用原型模式。例如,创建大量相似的图形对象、文档对象等。

1.2 关键要素与差异对比

模式关键要素差异
单例模式只有一个实例保证全局只有一个实例,提供全局访问点
简单工厂模式创建对象根据参数创建对象,但客户端需要知道具体类名
工厂方法模式抽象创建将创建逻辑抽象到子类中,客户端只需要关心接口
抽象工厂模式创建对象家族创建一系列相关或依赖对象,强调对象家族的约束条件
建造者模式复杂对象构建将构建过程与表示过程分离,支持多步骤构建
原型模式克隆对象通过复制现有对象来创建新对象,节省创建成本
模式名称实例唯一参数化实例化复杂对象构建对象族产品类层次多个构建步骤克隆
单例单一类别
简单工厂扁平结构
工厂方法分层结构
抽象工厂分层结构
建造者单一类别
原型单一类别
  • 实例唯一:模式是否确保一个类只有一个实例。
  • 参数化实例化:创建实例时是否允许传递参数,从而产生不同种类的对象。
  • 复杂对象构建:是否支持将复杂对象的创建分解成不同部分和步骤。
  • 对象族:是否支持一组相关的产品对象的系列。
  • 产品类层次:是否组织产品类的方式,扁平结构通常指每个类都是独立的,而分层结构则意着存在继承关系。
  • 多个构建步骤:创建对象是否包含一系列步骤。
  • 克隆:创建实例是否通过复制一个原型。

1.3 结构图

         

三、模式选择指南

    在实际的软件设计过程中,选择合适的创建型模式对于提高代码的可维护性、扩展性和灵活性至关重要。然而,面对多种创建型模式,如何选择最适合当前场景的模式可能会成为一项挑战。本部分将提供场景分析和决策流程图,以帮助读者在实际工作中做出恰当的选择。

3.1 场景分析

    在选择创建型模式时,首先要分析当前场景的特点和需求。以下是一些常见的场景及其对应的创建型模式:

 1. 当需要一个全局唯一的实例时:

  • 例如,配置管理、日志记录等场景,适合使用单例模式。这样可以确保整个系统中只有一个实例,避免重复创建和资源浪费。

 2. 当需要根据不同条件创建不同类型对象时:

  • 例如,根据用户输入或配置文件创建不同类型的数据库连接对象,适合使用简单工厂模式。简单工厂模式可以根据传入的参数创建并返回相应类型的对象。

 3. 当需要让子类决定创建何种对象时:

  • 例如,在设计图形绘制系统时,有多种不同类型的图形对象需要创建,适合使用工厂方法模式。工厂方法模式将对象的创建逻辑抽象到子类中,客户端只需要关心接口即可。

 4. 当需要创建一系列相互关联或依赖的对象时:

  • 例如,在设计主题皮肤或界面时,需要同时创建多个相互关联的对象,适合使用抽象工厂模式。抽象工厂模式可以创建并返回一系列相关或依赖的对象,而无需指定具体的类。

 5. 当需要构建复杂对象且构建过程与表示过程相互分离时:

  • 例如,在构建具有多个可选配置的复杂对象时,适合使用建造者模式。建造者模式可以将复杂对象的构建过程拆分为多个步骤,使得构建过程更加清晰和灵活。

 6. 当需要频繁创建相似对象且创建成本较高时:

  • 例如,在创建大量相似的图形对象或文档对象时,适合使用原型模式。原型模式可以通过复制现有对象来创建新对象,从而节省创建成本和时间。

3.2 决策流程图

    根据决策流程图,读者可以按照以下步骤进行选择:

  1. 确定是否需要全局唯一的实例:如果是,则选择单例模式;否则,继续下一步。
  2. 确定是否需要根据不同条件创建不同类型对象:如果是,则选择简单工厂模式;否则,继续下一步。
  3. 确定是否需要让子类决定创建何种对象:如果是,则选择工厂方法模式;否则,继续下一步。
  4. 确定是否需要创建一系列相互关联或依赖的对象:如果是,则选择抽象工厂模式;否则,继续下一步。
  5. 确定是否需要构建复杂对象且构建过程与表示过程相互分离:如果是,则选择建造者模式;否则,继续下一步。
  6. 确定是否需要频繁创建相似对象且创建成本较高:如果是,则选择原型模式;否则,可能需要考虑其他非创建型的设计模式或自定义解决方案。

    通过以上场景分析和决策流程图,信息读者可以更加清晰地了解各种创建型模式的适用场景和选择依据,从而在实际工作中做出恰当的选择。 

        

四、结语

    创建型设计模式在软件设计中扮演了至关重要的角色,它们为开发者提供了多样化的工具和方法,以灵活且优雅地创建对象。每种创建型设计模式都有其独特的优势和适用场景,正确使用它们可以提高代码的可维护性、扩展性和可重用性。

4.1 优势

 1. 封装性:

  • 创建型设计模式通常能够封装对象的创建逻辑,使得客户端代码与具体实现解耦,提高了代码的模块化和可维护性。

 2. 灵活性:

  • 这些模式允许我们在运行时根据需要创建对象,而不需要在编译时确定所有细节,这提供了很大的灵活性。

 3. 代码重用:

  • 通过复用创建逻辑,可以避免代码重复,提高代码的重用性。

 4. 扩展性:

  • 创建型设计模式能够支持软件的扩展和演化,因为它们允许在不修改现有代码的情况下添加新的对象类型。

4.2 考量因素

 1. 适用场景:

  • 选择创建型设计模式时,需要仔细分析应用场景,确保所选模式能够最有效地解决问题。

 2. 性能开销:

  • 虽然创建型设计模式可以提高代码的灵活性和可维护性,但在某些情况下,它们可能会引入额外的性能开销。因此,在选择模式时需要权衡其带来的好处和可能的性能影响。

 3. 设计复杂度:

  • 使用创建型设计模式可能会增加设计的复杂度,因此,在简单场景中过度使用可能会导致代码难以理解和维护。

 4. 学习成本:

  • 对于初学者来说,掌握并正确应用创建型设计模式可能需要一定的学习和实践成本。

    总的来说,创建型设计模式是软件设计中的重要工具,它们能够帮助开发者构建更加健壮、灵活和可维护的软件系统。然而,在实际应用中,我们需要根据具体场景和需求来选择合适的模式,并权衡其带来的好处和可能的成本。通过不断学习和实践,我们可以更好地掌握这些模式,并将它们应用于实际项目中,以提高软件的质量和效率。

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

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

相关文章

node+vue3+mysql前后分离开发范式——实现对数据库表的增删改查

文章目录 ⭐前言⭐ 功能设计与实现💖 node后端操作数据库实现增删改查💖 vue3前端实现增删改查⭐ 效果⭐ 总结⭐ 结束⭐结束⭐前言 大家好,我是yma16,本文分享关于 node+vue3+mysql前后分离开发范式——实现对数据库表的增删改查。 技术选型 前端:vite+vue3+antd 后端:…

使用radial-gradient完成弧形凹陷的绘制

1、效果如下图 我在微信小程序中制作的 2、代码如下 <style>.header {position: relative;width: 200px;height: 200px;overflow: hidden;}.header .circle {--circleValue: 500px;position: absolute;bottom: 0;left: 50%;width: 100%;height: var(--circleValue);trans…

[OPEN SQL] 修改数据

MODIFY语句用于修改数据库表中的数据 MODIFY拥有INSERT和UPDATE的操作&#xff0c;如果数据库表中不存在符合条件的数据则会添加该条新数据&#xff0c;反之数据库表中存在符合条件的数据则会更新该条数据 本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航…

【git】.gitignore 的匹配规则

每行一个规则&#xff1a;每行只能包含一个规则&#xff0c;多个规则需要分别写在不同的行上。 示例&#xff1a; # 忽略日志文件 logs/ # 忽略临时文件 temp.txt种类匹配&#xff1a; 文件&#xff1a;在规则的开头指定文件名或路径&#xff0c;如 file.txt。 示例&#xff1a…

HGAME2024 WEEK2 wp webmisc

web What the cow say? 进入容器有个输入框&#xff0c;尝试ssti、命令执行、代码执行等&#xff0c;最后发现可使用反引号执行命令&#xff1b; 输入 nl app.py 可查看源代码&#xff0c;有功能具体实现、过滤之类的&#xff1b; flag在 /flag_is_here home/flag_c0w54y 中…

每日OJ题_递归②_力扣21. 合并两个有序链表

目录 力扣21. 合并两个有序链表 解析代码 力扣21. 合并两个有序链表 21. 合并两个有序链表 难度 简单 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4]…

CSS设置盒子阴影

语法 box-shadow: *h-shadow v-shadow blur spread color* inset; 注释: box-shadow向框添加一个或多个阴影. 该属性是由逗号分隔的阴影列表,每个阴影由2-4个长度值、可选的颜色值及可选的inset关键词来规定。省略长度的值是0。 外阴影 a、给元素右边框和下边框加外阴影——把…

LabVIEW虚拟测试与分析仪

LabVIEW虚拟测试与分析仪 在现代工程技术领域&#xff0c;虚拟仪器的开发和应用已成为一种趋势。利用LabVIEW软件平台开发的虚拟测试与分析仪器进行展开&#xff0c;实现工程测试和分析中的实际需求。通过结合LabVIEW的强大功能和灵活性&#xff0c;成功实现了一套高效、精确的…

Gemini 1.5 Pro揭秘:Google DeepMind新一代AI模型如何突破千万级别词汇限制?

Gemini 1.5 Pro 发布&#xff01; 这款模型凭借其超长的上下文处理能力脱颖而出&#xff0c;支持10M tokens。 它的多模态特性意味着&#xff0c;无论面对多么庞大复杂的内容&#xff0c;Gemini 1.5 Pro都能游刃有余地应对。 在AI的世界里&#xff0c;上下文的理解如同记忆的…

嵌入式中UART通信的方法

UART是一种异步全双工串行通信协议&#xff0c;由 Tx 和 Rx 两根数据线组成&#xff0c;因为没有参考时钟信号&#xff0c;所以通信的双方必须约定串口波特率、数据位宽、奇偶校验位、停止位等配置参数&#xff0c;从而按照相同的速率进行通信。 异步通信以一个字符为传输单位…

插值(一)——多项式插值(C++)

插值 插值的作用是可以将原本比较难计算的函数转换为误差在一定范围内的多项式&#xff0c;比如在单片机中直接计算 x 、 log ⁡ 2 x \sqrt{x}、\log_2x x ​、log2​x之类的函数是比较麻烦的&#xff0c;但是使用插值的方法就可以将其转换为误差可控的只有乘法和加减法的多项…

MySQL学习记录——팔 函数

文章目录 1、日期函数2、字符串函数3、数学函数4、其它函数 1、日期函数 //获取日期 select current_date(); //获取时间 select current_time(); //获取时间戳, 格式为日期时间 select current_timestamp(); //获取当前时间, 格式为日期时间 select now(); //获取参数的日期部…

Leetcode-1572. 矩阵对角线元素的和

题目&#xff1a; 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1a; 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;25 解释&#xff1a;对角线…

RK3568笔记十六:Framebuffer实验

若该文为原创文章&#xff0c;转载请注明原文出处。 本意是移植LVGL&#xff0c;但在编译DRM过程中一直编译失败&#xff0c;然后就想Framebuffer是否可以用&#xff0c;所以测试一下。 一、framebuffer介绍 FrameBuffer中文译名为帧缓冲驱动&#xff0c;它是出现在2.2.xx内…

leetcode(二分查找)34.在排序数组中查找元素的第一个和最后一个位置(C++详细解释)DAY11

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计…

SECS/GEM的HSMS通讯?金南瓜方案

High Speed SECS Message Service (HSMS) 是一种基于 TCP/IP 的协议&#xff0c;它使得 SECS 消息通信更加快速。这通常用作设备间通信的接口。 HSMS 状态逻辑变化&#xff08;序列&#xff09;&#xff1a; 1.Not Connected&#xff1a;准备初始化 TCP/IP 连接&#xff0c;但尚…

【C深度解剖】取模与取余

简介&#xff1a;本系列博客为C深度解剖系列内容&#xff0c;以某个点为中心进行相关详细拓展 适宜人群&#xff1a;已大体了解C语法同学 作者留言&#xff1a;本博客相关内容如需转载请注明出处&#xff0c;本人学疏才浅&#xff0c;难免存在些许错误&#xff0c;望留言指正 作…

SpringCloud之Nacos用法笔记

SpringCloud之Nacos注册中心 Nacos注册中心nacos启动服务注册到Nacosnacos服务分级模型NacosRule负载均衡策略根据集群负载均衡加权负载均衡Nacos环境隔离-namespace Nacos与eureka的对比临时实例与非临时实例设置 Nacos配置管理统一配置管理微服务配置拉取配置自动刷新远端配置…

1232.缀点成线(Java)

题目描述&#xff1a; 给定一个数组 coordinates &#xff0c;其中 coordinates[i] [x, y] &#xff0c; [x, y] 表示横坐标为 x、纵坐标为 y 的点。请你来判断&#xff0c;这些点是否在该坐标系中属于同一条直线上。 输入&#xff1a; coordinates [[1,2],[2,3],[3,4],[4,5]…

机器学习:数据集划分笔记

数据集划分是机器学习中非常关键的步骤&#xff0c;能直接影响模型的训练效果和泛化能力。它的主要目的是为了评估模型对新数据的泛化能力&#xff0c;即模型在未见过的数据上能表现良好。 数据集通常被划分为三个部分&#xff1a;训练集&#xff08;Training set&#xff09;、…