【再谈设计模式】抽象工厂模式~对象创建的统筹者

一、引言

        在软件开发的世界里,高效、灵活且易于维护的代码结构是每个开发者追求的目标。设计模式就像是建筑蓝图中的经典方案,为我们提供了应对各种常见问题的有效策略。其中,抽象工厂模式在对象创建方面扮演着重要的角色,它如同一个统筹者,精心组织着一系列相关对象的创建过程,确保整个系统的高效运转和易于扩展。无论是构建大型企业级应用还是小型工具软件,理解和运用抽象工厂模式都能让我们的代码更加优雅、健壮。

二、定义与描述

        抽象工厂设计模式是一种创建对象的设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。简单来说,抽象工厂模式就像是一个工厂的抽象层,这个抽象层定义了创建多种不同类型产品的方法,但不涉及具体产品的创建细节。

三、抽象背景

        在软件开发中,当系统需要创建一系列相关的对象时,例如一个游戏可能需要创建不同类型的角色(战士、法师等)以及与这些角色相关的武器、装备等对象。如果直接在代码中实例化这些对象,将会导致代码的高度耦合,即对象的创建逻辑与使用逻辑紧密地交织在一起。当需要添加新的角色类型或者修改对象的创建逻辑时,就需要在大量的代码中进行修改,这不仅容易出错,而且维护成本极高。抽象工厂模式的出现就是为了解决这种对象创建的复杂性和耦合性问题。

四、适用场景与现实问题解决

(一)适用场景

  • 多平台应用开发
    • 当开发一个跨平台的应用时,例如同时支持Windows、Linux和Mac操作系统的图形界面应用。不同平台下的窗口、按钮、菜单等界面组件虽然功能相似,但实现方式不同。抽象工厂模式可以用于创建与特定平台相关的界面组件系列,使得代码能够轻松地在不同平台间切换,而不需要在每个使用界面组件的地方都进行大量的条件判断。

  • 游戏开发
    • 在游戏中,不同的游戏场景可能需要不同类型的游戏元素。例如,一个冒险游戏可能有森林场景、沙漠场景等,每个场景中都有独特的怪物、道具和地形。抽象工厂模式可以用来创建这些与特定场景相关的游戏元素系列,保证游戏元素之间的兼容性和一致性。

(二)现实问题解决

  • 假设我们正在开发一个汽车制造系统。汽车由多个部件组成,如发动机、轮胎、座椅等,并且有不同类型的汽车,如轿车、SUV等。使用抽象工厂模式,我们可以创建抽象的汽车部件工厂,它定义了创建发动机、轮胎和座椅等部件的抽象方法。然后针对轿车和SUV分别创建具体的工厂实现类,这些具体工厂类负责创建各自类型汽车所需的特定部件。这样,当需要添加一种新类型的汽车时,只需要创建一个新的具体工厂类,而不需要修改使用这些部件的汽车组装代码,从而降低了系统的耦合度,提高了可维护性和可扩展性。

五、现实生活的例子

        以家具制造为例。家具厂可以看作是一个抽象工厂,它有生产不同风格家具(如现代风格、古典风格)的能力。对于现代风格家具,工厂可以生产现代风格的沙发、餐桌和椅子;对于古典风格家具,工厂可以生产古典风格的沙发、餐桌和椅子。这里,家具厂就是抽象工厂,它定义了生产沙发、餐桌和椅子的抽象方法,而现代风格家具厂和古典风格家具厂就是具体的工厂实现类,它们按照各自的风格生产具体的家具产品。

六、初衷与问题解决

  • 初衷:抽象工厂模式的初衷是为了将对象的创建和使用分离,提高代码的灵活性和可维护性。通过提供一个抽象的创建对象的接口,使得代码的依赖关系更加抽象化,减少对具体类的依赖。
  • 问题解决:它解决了对象创建逻辑与使用逻辑耦合的问题。在大型软件系统中,如果没有这种模式,每当需要创建新类型的对象或者修改对象的创建逻辑时,可能需要在多个地方修改代码。而抽象工厂模式通过将对象创建逻辑封装在具体的工厂类中,只需要修改或扩展工厂类,而不需要影响使用这些对象的其他代码部分。

七、代码示例

(一)Java示例

// 抽象产品:座椅
interface Seat {void sitOn();
}// 抽象产品:轮胎
interface Tire {void roll();
}// 抽象产品:发动机
interface Engine {void start();
}// 抽象工厂
interface CarFactory {Seat createSeat();Tire createTire();Engine createEngine();
}// 具体产品:轿车座椅
class SedanSeat implements Seat {@Overridepublic void sitOn() {System.out.println("坐在轿车座椅上。");}
}// 具体产品:轿车轮胎
class SedanTire implements Tire {@Overridepublic void roll() {System.out.println("轿车轮胎滚动。");}
}// 具体产品:轿车发动机
class SedanEngine implements Engine {@Overridepublic void start() {System.out.println("轿车发动机启动。");}
}// 具体工厂:轿车工厂
class SedanFactory implements CarFactory {@Overridepublic Seat createSeat() {return new SedanSeat();}@Overridepublic Tire createTire() {return new SedanTire();}@Overridepublic Engine createEngine() {return new SedanEngine();}
}public class Main {public static void main(String[] args) {CarFactory sedanFactory = new SedanFactory();Seat sedanSeat = sedanFactory.createSeat();Tire sedanTire = sedanFactory.createTire();Engine sedanEngine = sedanFactory.createEngine();sedanSeat.sitOn();sedanTire.roll();sedanEngine.start();}
}

(二)C++示例

#include <iostream>// 抽象产品:座椅
class Seat {
public:virtual void sitOn() = 0;
};// 抽象产品:轮胎
class Tire {
public:virtual void roll() = 0;
};// 抽象产品:发动机
class Engine {
public:virtual void start() = 0;
};// 抽象工厂
class CarFactory {
public:virtual Seat* createSeat() = 0;virtual Tire* createTire() = 0;virtual Engine* createEngine() = 0;
};// 具体产品:轿车座椅
class SedanSeat : public Seat {
public:void sitOn() override {std.out << "坐在轿车座椅上。" << std::endl;}
};// 具体产品:轿车轮胎
class SedanTire : public Tire {
public:void roll() override {std::cout << "轿车轮胎滚动。" << std::endl;}
};// 具体产品:轿车发动机
class SedanEngine : public Engine {
public:void start() override {std::cout << "轿车发动机启动。" << std::endl;}
};// 具体工厂:轿车工厂
class SedanFactory : public CarFactory {
public:Seat* createSeat() override {return new SedanSeat();}Tire* createTire() override {return new SedanTire();}Engine* createEngine() override {return new SedanEngine();}
};int main() {CarFactory* sedanFactory = new SedanFactory();Seat* sedanSeat = sedanFactory->createSeat();Tire* sedanTire = sedanFactory->createTire();Engine* sedanEngine = sedanFactory->createEngine();sedanSeat->sitOn();sedanTire->roll();sedanEngine->start();delete sedanSeat;delete sedanTire;delete sedanEngine;delete sedanFactory;return 0;
}

(三)Python示例

# 抽象产品:座椅
class Seat:def sitOn(self):pass# 抽象产品:轮胎
class Tire:def roll(self):pass# 抽象产品:发动机
class Engine:def start(self):pass# 抽象工厂
class CarFactory:def createSeat(self):passdef createTire(self):passdef createEngine(self):pass# 具体产品:轿车座椅
class SedanSeat(Seat):def sitOn(self):print("坐在轿车座椅上。")# 具体产品:轿车轮胎
class SedanTire(Tire):def roll(self):print("轿车轮胎滚动。")# 具体产品:轿车发动机
class SedanEngine(Engine):def start(self):print("轿车发动机启动。")# 具体工厂:轿车工厂
class SedanFactory(CarFactory):def createSeat(self):return SedanSeat()def createTire(self):return SedanTire()def createEngine(self):return SedanEngine()if __name__ == "__main__":sedanFactory = SedanFactory()sedanSeat = sedanFactory.createSeat()sedanTire = sedanFactory.createTire()sedanEngine = sedanFactory.createEngine()sedanSeat.sitOn();sedanTire.roll();sedanEngine.start();

(四)Go示例

// 抽象产品:座椅
type Seat interface {SitOn()
}// 抽象产品:轮胎
type Tire interface {Roll()
}// 抽象产品:发动机
type Engine interface {Start()
}// 抽象工厂
type CarFactory interface {CreateSeat() SeatCreateTire() TireCreateEngine() Engine
}// 具体产品:轿车座椅
type SedanSeat struct{}func (s SedanSeat) SitOn() {println("坐在轿车座椅上。")
}// 具体产品:轿车轮胎
type SedanTire struct{}func (s SedanTire) Roll() {println("轿车轮胎滚动。")
}// 具体产品:轿车发动机
type SedanEngine struct{}func (s SedanEngine) Start() {println("轿车发动机启动。")
}// 具体工厂:轿车工厂
type SedanFactory struct{}func (s SedanFactory) CreateSeat() Seat {return SedanSeat{}
}
func (s SedanFactory) CreateTire() Tire {return SedanTire{}
}
func (s SedanFactory) CreateEngine() Engine {return SedanEngine{}
}func main() {sedanFactory := SedanFactory{}sedanSeat := sedanFactory.CreateSeat()sedanTire := sedanFactory.CreateTire()sedanEngine := sedanFactory.CreateEngine()sedanSeat.SitOn()sedanTire.Roll()sedanEngine.Start()
}

八、抽象工厂设计模式的优缺点

(一)优点

  • 解耦对象的创建和使用
    • 使用者不需要知道对象的具体创建过程,只需要关心如何使用对象。这使得代码的职责更加清晰,有利于团队开发和代码维护。
  • 提高代码的可维护性和可扩展性
    • 当需要添加新的产品类型或者修改产品的创建逻辑时,只需要在具体的工厂类中进行操作,不需要修改使用这些对象的其他代码部分。
  • 便于代码的复用
    • 抽象工厂可以被多个地方复用,只要这些地方需要创建相同系列的产品。同时,具体的产品类也可以在其他场景下复用。

(二)缺点

  • 增加代码复杂度
    • 引入抽象工厂模式需要创建更多的类和接口,对于简单的应用场景,可能会使代码变得过于复杂。
  • 不易于理解
    • 对于初学者或者不熟悉设计模式的开发人员来说,抽象工厂模式的概念和实现方式可能比较难以理解,需要一定的学习成本。

九、抽象工厂设计模式的升级版

  • 抽象工厂模式的一个升级版是工厂方法模式的组合使用。在大型系统中,可能会存在多个抽象工厂,每个抽象工厂又可以有多个具体的工厂方法。这种组合模式可以进一步细化对象的创建逻辑,提高代码的灵活性。例如,在汽车制造系统中,可以先有一个抽象的汽车部件总装工厂(抽象工厂),然后这个总装工厂中的每个部件创建可以采用工厂方法模式,即发动机的创建有专门的发动机工厂方法,轮胎的创建有专门的轮胎工厂方法等。这样可以更加细致地管理和扩展对象的创建逻辑。

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

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

相关文章

R语言机器学习与临床预测模型77--机器学习预测常用R语言包

R小盐准备介绍R语言机器学习与预测模型的学习笔记 你想要的R语言学习资料都在这里&#xff0c; 快来收藏关注【科研私家菜】 01 预测模型常用R包 常见回归分析包: rpart 包含有分类回归树的方法; earth 包可以实现多元自适应样条回归; mgev包含广义加性模型回归; Rweka 包中的M…

使用OpenGL ES简单实现一个特效

玩抖音的时候&#xff0c;刷到一个抖音红发GET特效&#xff0c;感觉实现起来应该不太难。 于是小试牛刀。以刷到的一个视频一帧为原图 抖音红发GET特效拍出来的效果为 我实现的效果为&#xff1a; 基于Android平台&#xff0c;以OpenGL ES为工具&#xff0c;开发了一个滤镜…

豆包MarsCode算法题:数组元素之和最小化

数组元素之和最小化 问题描述思路分析分析思路解决方案 参考代码&#xff08;Python&#xff09;代码分析1. solution 函数2. 计算 1 2 3 ... n 的和3. 乘以 k 得到最终的数组元素之和4. 主程序&#xff08;if __name__ __main__:&#xff09;代码的时间复杂度分析&#x…

WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇

WebRTC视频 01 - 视频采集整体架构 WebRTC视频 02 - 视频采集类 VideoCaptureModule WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇 WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇 WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇&#xff08;本文&#xff09; 一、前言…

ffmpeg 最强大的视频工具

文章目录 一、ffmpeg安装二、基本用法1、文件格式转换2、视频过滤器 filter3、剪切4、合并5、音频过滤器6、删除轨道7、简单应用&#xff1a;录屏 一、ffmpeg安装 windows下可以上官网 https://www.ffmpeg.org/download.html下载&#xff1a; 下载好后&#xff0c;解压缩&…

初识算法 · 位运算(2)

目录 前言&#xff1a; 判定字符是否唯一 丢失的数字 比特位计数 只出现一次的数字III 前言&#xff1a; ​本文的主题是位运算&#xff0c;通过四道题目讲解&#xff0c;一道是判断字符是否唯一&#xff0c;一道是只出现一次的数字III&#xff0c;一道是比特位计数&…

大数据新视界 -- 大数据大厂之 Impala 性能优化:基于数据特征的存储格式选择(上)(19/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

[产品管理-76]:延续是创新与颠覆式创新的比较

目录 一、概述 1、定义与特征 2、市场影响与竞争策略 3、实施难度与风险 4、案例分析 二、示例 1. 延续性创新示例 2. 创新示例 3. 颠覆式创新示例 一、概述 延续性创新与颠覆式创新是技术创新领域的两种重要策略&#xff0c;它们在多个方面存在显著差异。 以下是对…

JAVA学习日记(十五) 数据结构

一、数据结构概述 数据结构是计算机底层存储、组织数据的方式。 数据结构是指数据相互之间以什么方式排列在一起的。 数据结构是为了更加方便的管理和使用数据&#xff0c;需要结合具体的业务场景来进行选择。 二、常见的数据结构 &#xff08;一&#xff09;栈 特点&…

自动化测试工具Ranorex Studio(三十)-代码模块中使用变量快照

为了在代码模块中使用数据连接器提供的值&#xff0c;你需要在代码中添加一个变量。使用右键菜单项’Insert Module Variable’。 添加一个新的变量到您的代码模块 指定变量名和默认值 通过添加一个新的变量&#xff0c;Ranorex Studio 会在光标位置插入一段新代码——由一个…

Python技巧:查询模块的版本号的方法

1,pycharm里面的 Python interpreter 或者 Python package 2&#xff0c;通过 __version_info__ import matplotlib print(matplotlib.__version_info__) 3&#xff0c;查看目录里面的 _version.py 文件

​​​​​​​15TS Series TVS 的解析

15TS Series 1500W Transient Voltage Suppresso指的是一系列高性能的瞬态电压抑制二极管&#xff08;Transient Voltage Suppressor&#xff0c;TVS&#xff09;&#xff0c;这些二极管由时源芯微&#xff08;TimeSource&#xff09;设计用于保护敏感的电子设备免受瞬态过电压…

Python学习从0到1 day27 Python 高阶技巧 ① 闭包

目录 一、闭包 作用 示例 二、nonlocal关键字 示例 三、atm取钱的闭包实现 四、闭包注意事项 优点 缺点 我陪你走了一段路&#xff0c;你最了解我不是吗 —— 24.11.11 一、闭包 在函数嵌套的前提下&#xff0c;内部函数使用了外部函数的变量&#xff0c;并且外部函数返回了内部…

python成长技能之网络编程

文章目录 一、初识Socket1.1 什么是 Socket?1.2 socket的基本操作1.3 socket常用函数 二、基于UDP实现客户端与服务端通信三、基于TCP实现客户端与服务端通信四、使用requests模块发送http请求 一、初识Socket 1.1 什么是 Socket? Socket又称"套接字"&#xff0c;…

[ACTF2020 新生赛]Upload 1--详细解析

信息收集 题目告诉我们是一道upload&#xff0c;也就是文件上传漏洞题目。 进入界面&#xff0c;是一个灯泡&#xff0c;将鼠标放在图标上就会出现文件上传的相应位置&#xff1a; 思路 文件上传漏洞&#xff0c;先看看有没有前端校验。 在js源码中找到了前端校验&#xff…

光伏设计软件怎么选?有哪些推荐?

在光伏电站的开发建设中&#xff0c;专业设计软件是提升电站能效、降低开发成本的重要工具。市场上存在许多优秀的光伏设计软件&#xff0c;能够通过还原现状和三维建模来呈现出最符合实际需求的设计方案&#xff0c;究竟该怎么选呢&#xff1f; -易用性&#xff1a;一些软件操…

刷题强训(day06) -- 大数加法、链表相加、大数乘法

目录 1、大数加法 1.1 题目 1.2 思路 1.3 代码实现 2、链表相加&#xff08;二&#xff09; 2.1 题目 2.2 思路 2.3 代码实现 3、大数乘法 3.1 题目 3.2 思路 3.3 代码实现 1、大数加法 1.1 题目 1.2 思路 这道题可以模拟列竖式相加解答&#xff0c; 将每一位都转…

雷池waf安装并部署防护站点

雷池waf安装并部署防护站点 最低配置要求 操作系统&#xff1a;Linux 指令架构&#xff1a;x86_64 软件依赖&#xff1a;Docker 20.10.14 版本以上 软件依赖&#xff1a;Docker Compose 2.0.0 版本以上 最小化环境&#xff1a;1 核 CPU / 1 GB 内存 / 5 GB 磁盘 写在前面 本文…

AI技术赋能电商行业:创新应用与未来展望

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《热点时事》 期待您的关注 引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐步渗透到各行各业&a…

【Linux】进程(状态)

大家好呀&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流哦 本文由&#xff1a;残念ing原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&#xff0c;欢迎各…