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

一、引言

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

二、定义与描述

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

三、抽象背景

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

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

(一)适用场景

  • 多平台应用开发
    • 当开发一个跨平台的应用时,例如同时支持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.rhkb.cn/news/470506.html

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

相关文章

Web安全之SQL注入---基础

文章目录 SQL注入简介SQL注入基础SQL注入分类SQL注入流程 SQL注入简介 什么是SQL注入&#xff1f; SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理…

机器学习——贝叶斯

&#x1f33a;历史文章列表&#x1f33a; 机器学习——损失函数、代价函数、KL散度机器学习——特征工程、正则化、强化学习机器学习——常见算法汇总机器学习——感知机、MLP、SVM机器学习——KNN机器学习——贝叶斯机器学习——决策树机器学习——随机森林、Bagging、Boostin…

gdb编译教程(支持linux下X86和ARM架构)

1、下载源码 http://ftp.gnu.org/gnu/gdb/ 我下载的8.2版本。 2、下载完后拷贝到linux的x86系统。 3、解压&#xff0c;然后进入到目录下&#xff0c;打开当前目录的命令行窗口。 4、创建一个生成目录。 5、我们先开始x86版本&#xff0c;这个比较简单&#xff0c;不需要配置…

10款翻译工具实践体验感受与解析!!!!!

在现今的数字化时代&#xff0c;翻译工具如同语言的桥梁&#xff0c;为我们打开了通向世界的大门。今天咱们不聊别的&#xff0c;就聊聊那些让我又爱不释手的翻译工具们。因为我的职业因素&#xff0c;作为一个经常需要跟各种语言打交道的“文字搬运工”&#xff0c;这些工具可…

【日志】392.判断子序列

2024.11.8 【力扣刷题】 392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/is-subsequence/?envTypestudy-plan-v2&envIdtop-interview-150 整个题从一开始就是打算从双指针的思想往下走的。但是&#xff0c;我设置了四个变量sLeft…

C++20 中最优雅的那个小特性 - Ranges

C20 中最优雅的那个小特性 - Ranges 大家好&#xff0c;今天我们来聊聊 C20 的一项非常重要的新特性——Ranges&#xff0c;可以让你的代码更优雅、更高效、更炫酷&#xff0c;如果你是一个对代码有所追求的小伙伴&#xff0c;那么这个特性你绝对值得拥有&#xff01; 啥是 …

Python多进程间通讯(包含共享内存方式)

文章目录 1 通过非共享内存配合队列方式2 通过共享内存配合队列方式 注&#xff1a;本博文测试环境为Linux系统。 1 通过非共享内存配合队列方式 下面是一个常见的生产者与消费者的模式示例&#xff0c;这里分别启动了两个子进程&#xff0c;一个为生产者&#xff08;producer…

深入理解接口测试:实用指南与最佳实践5.0(一)

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

2024.11.12_大数据的诞生以及解决的问题

大数据的诞生以及解决的问题 视频一&#xff1a;大数据诞生的背景原因&#xff1a;传统的数据处理架构无法满足海量的数据存储和计算需求 视频三&#xff1a;区分离线处理场景和实时处理场景视频五&#xff1a;传统的大数据与现代的大数据区别&#xff08;离线场景&#xff09;…

ML 系列: 第 24 节 — 离散概率分布(泊松分布)

目录 一、说明 二、固定时间间隔示例 三、固定间隔的示例 四、泊松分布的主要特征 五、示例 5.1 平均客户数的计算&#xff1a; 5.2 用于计算和绘制泊松分布的 Python 代码&#xff1a; 一、说明 泊松概率分布是一种离散概率分布&#xff0c;它表示在固定的时间或空间间隔内发生…

闯关leetcode——3174. Clear Digits

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/clear-digits/description/ 内容 You are given a string s. Your task is to remove all digits by doing this operation repeatedly: Delete the first digit and the closest non-digit cha…

机器情绪及抑郁症算法

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月12日17点02分 点击开启你的论文编程之旅https://www.aspiringcode.com/content?id17230869054974 计算机来理解你的情绪&a…

【深圳大学】数据结构A+攻略(计软版)

1. 考试 1.1 形式 分为平时&#xff0c;笔试&#xff0c;机试三部分。其中&#xff1a; 平时占30%&#xff0c;包含平时OJ测验和课堂练习&#xff0c;注意这个可能会因老师的不同和课题组的新策略而改变。笔试占60%&#xff0c;是分值占比的主要部分。机试占10%。 1.2 题型…

Chrome使用IE内核

Chrome使用IE内核 1.下载扩展程序IE Tab 2.将下载好的IE Tab扩展程序拖拽到扩展程序界面&#xff0c;之后重启chrome浏览器即可

使用pytest+openpyxl做接口自动化遇到的问题

最近使用pytestopenpyxl做了个接口自动化的小项目&#xff0c;遇到了一些问题。 首先&#xff0c;使用pytest这个框架&#xff0c;主要是使用了pytest.fixture, pytest.mark.parametrize这两个fixture去做参数化&#xff0c;里面注入的数据是用openpyxl来实现的。 接口介绍&a…

IEC60870-5-104 协议源码架构详细分析

IEC60870-5-104 协议源码架构 前言一、资源三、目录层级一二、目录层级二config/lib60870_config.hdependencies/READMEexamplesCMakeLists.txtcs101_master_balancedcs104_client_asyncmulti_client_servertls_clienttls_server说明 make这些文件的作用是否需要导入这些文件&a…

TensorRT基础知识

github:https://github.com/NVIDIA/TensorRT 官网快速入门链接&#xff1a;Quick Start Guide :: NVIDIA Deep Learning TensorRT Documentation 引言&#xff1a; TensorRT 是 NVIDIA 推出的一个高性能深度学习推理库&#xff0c;专门用于优化和加速已经训练好的深度学习模型…

jenkins提交gitee后自动部署

jenkins中安装gitee插件 Gitee Plugin​​​​​​ 配置gitee WebHook 生成giteeHook密码 去gitee中配置webHook 输入jenkins中的url和生成的密码 当我们再提交后就可以自动部署 gitee官方配置

软件测试面试八股文(超详细整理)

请你说一说测试用例的边界 参考回答&#xff1a; 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充&#xff0c;这种情况下&#xff0c;其测试用例来自等价类的边界。 常见的边界值 1)对16-bit 的整数而言 32…

【金融风控】特征评估与筛选详解

内容介绍 掌握单特征分析的衡量指标 知道 IV&#xff0c;PSI等指标含义 知道多特征筛选的常用方法 掌握Boruta,VIF,RFE,L1等特征筛选的使用方法 【理解】单特征分析 什么是好特征 从几个角度衡量&#xff1a;覆盖度&#xff0c;区分度&#xff0c;相关性&#xff0c;稳定…