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

news/2024/11/17 23:54:35/

一、引言

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

二、定义与描述

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

三、抽象背景

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

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

(一)适用场景

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

相关文章

Linux系统制作Java JAR程序为系统服务

在Linux系统中&#xff0c;将JAR程序制作成系统服务可以通过系统自带的systemd服务管理器来实现。systemd是现代Linux系统中广泛使用的初始化系统和服务管理器&#xff0c;它提供了强大的功能来管理系统的启动和服务。 以下是将JAR程序制作成systemd系统服务的步骤&#xff0c…

2024-11-16 特殊矩阵的压缩存储

一、数组的存储结构 1.一维数组&#xff1a;各元素大小相同&#xff0c;且物理上连续存放。a[i]起始地址i*siezof(数组元素大小) 2.二维数组&#xff1a;b[j][j]起始地址&#xff08;i*Nj&#xff09;*sizeof(数组元素大小) 二、特殊矩阵 1.普通矩阵的存储&#xff1a;使用…

酷炫的鼠标移入效果(附源码!!)

预览效果 源码(htmljs部分) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title>…

对称加密算法DES的实现

一、实验目的 1、了解对称密码体制基本原理 2、掌握编程语言实现对称加密、解密 二、实验原理 DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位&#xff0c;产生最大 64 位的分组大小。这是一个迭代的分组密码&#xff0c;使用称为 Feistel 的技术&#xff0c;其中将加密…

基于机器学习的虚拟传感器用于门开启检测和异常检测

论文标题&#xff1a;Virtual sensor for door opening detection and anomaly detection using machine learning&#xff08;基于机器学习的虚拟传感器用于门开启检测和异常检测&#xff09; 作者信息&#xff1a; Almir Neto&#xff0c;来自巴西马拉尼昂联邦教育、科学与…

前端传数组 数据库存Json : [1,2,3]格式

一、前端正常传数组&#xff0c;但是value.toString() 即可 const empIds ref([1,2,3]) empIds.value empIds.value.toString() await updateApiRules(empIds.value) // 接口传参 二、后端用String类型接收后转换 String[] empIds updateDO.getEmpId().split("&#x…

ssm113ssm框架的购物网站+vue(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;网上超市系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本网上超市系统就是在这…

【Python爬虫实战】轻量级爬虫利器:DrissionPage之SessionPage与WebPage模块详解

&#x1f308;个人主页&#xff1a;易辰君-CSDN博客 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、SessionPage &#xff08;一&#xff09;SessionPage 模块的基本功能 &#xff08;二&#xff09;基本使…