当前位置: 首页 > java >正文

三,设计模式-抽象工厂模式

目的

在 工厂模式 中,当需要创建新的产品时,则额外需要创建新的工厂,这种模式是对产品制造方法的抽象化,如果产品种类变多,则工厂数目变多,则代码规模会越来越大,且不同的产品类的生成依赖不同的工厂。为了解决上述问题,则提出了新的模式-抽象工厂模式。抽象工厂模式是对工厂的抽象化,即假设工厂不会只局限于生产一类产品,而是生产多系列产品。以汽车工厂为例,可能有多个品牌的汽车厂,每个汽车厂都可以/可能生产多种产品,如跑车、越野车等系列产品,那我们就有了下面的表格:

轿车越野车卡车
A品牌车厂A1A2A3
B品牌车厂B1B2B3

A品牌车厂、B品牌车厂就类似一个个具体的生产工厂,轿车、越野车、卡车就是一系列的具体产品,抽象工厂不仅对产品进行抽象(统一接口),同时对工厂也进行抽象(统一接口,接口用来生产具体的系列产品)。

抽象工厂模式适用于如下场景:

  • 需要与多个不同系列的相关产品交互, 出于对未来扩展性的考虑, 不希望代码基于产品的具体类进行构建, 在这种情况下, 可以使用抽象工厂;抽象工厂提供了一个(或一套)接口, 可用于创建每个系列产品的对象。 只要代码通过该接口创建对象,就不会生成与应用程序已生成的产品类型不一致的产品;

实现

  1. 产品类型(可能有多个,列)与产品体系/产品变体(产品类型数目一致,但产品类型实现方式不同,行)为维度绘制矩阵。

  2. 声明抽象产品接口(不同的产品类型的共同接口),让所有具体产品类实现这些接口。

  3. 声明抽象工厂接口(不同产品体系/产品变体的共同接口), 并在接口中为所有抽象产品提供一组构建方法。

  4. 为每种产品体系/产品变体实现一个具体工厂类。

  5. 修改应用程序的初始化代码,代码中根据应用程序配置或当前环境, 对特定具体工厂类进行初始化,并将该工厂对象传递给所有需要创建产品的类。

  6. 找出代码中所有对产品构造函数的直接调用, 将其替换为对工厂对象中相应构建方法的调用。

具体代码实现如下,这里以抽象工厂模式的应用场景UI为例:

#include <iostream>
#include <memory>class Button {
public:virtual void render() = 0;virtual ~Button() = default;
};class Checkbox {
public:virtual void render() = 0;virtual ~Checkbox() = default;
};class WindowsButton : public Button {
public:void render() override {std::cout << "Rendering Windows Button\n";}
};class WindowsCheckbox : public Checkbox {
public:void render() override {std::cout << "Rendering Windows Checkbox\n";}
};class MacButton : public Button {
public:void render() override {std::cout << "Rendering Mac Button\n";}
};class MacCheckbox : public Checkbox {
public:void render() override {std::cout << "Rendering Mac Checkbox\n";}
};class GUIFactory {
public:virtual std::unique_ptr<Button> createButton() = 0;virtual std::unique_ptr<Checkbox> createCheckbox() = 0;virtual ~GUIFactory() = default;
};class WindowsFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<WindowsButton>();}std::unique_ptr<Checkbox> createCheckbox() override {return std::make_unique<WindowsCheckbox>();}
};class MacFactory : public GUIFactory {
public:std::unique_ptr<Button> createButton() override {return std::make_unique<MacButton>();}std::unique_ptr<Checkbox> createCheckbox() override {return std::make_unique<MacCheckbox>();}
};void renderUI(GUIFactory& factory) {auto button = factory.createButton();auto checkbox = factory.createCheckbox();button->render();checkbox->render();
}int main() {WindowsFactory winFactory;MacFactory macFactory;std::cout << "Using Windows Factory:\n";renderUI(winFactory);std::cout << "\nUsing Mac Factory:\n";renderUI(macFactory);return 0;
}

http://www.xdnf.cn/news/18474.html

相关文章:

  • 深入解析TCP/UDP协议与网络编程
  • Leetcode—120. 三角形最小路径和【中等】(腾讯校招面试题)
  • SSM框架基础知识-Spring-Spring整合MyBatis
  • 基于SpringBoot+Vue框架的高校论坛系统 博客论坛系统 论坛小程序
  • 图神经网络分享系列-LINE(三)
  • Oracle SYS用户无法登录数据库-ORA-12162
  • Chrome和Edge如何开启暗黑模式
  • 本地部署DeepSeek实战
  • CS 创世 SD NAND 助力 T-BOX:破解智能汽车数字中枢的存储密码
  • 【UniApp打包鸿蒙APP全流程】如何配置并添加UniApp API所需的鸿蒙系统权限
  • 使用隧道(Tunnel)连接PostgreSQL数据库(解决防火墙问题)
  • 【Ansible】变量与敏感数据管理:Vault加密与Facts采集详解
  • 使用PPT进行科研绘图过程中常用的快捷键
  • Matplotlib 可视化大师系列(八):综合篇 - 在一张图中组合多种图表类型
  • Android 广告轮播全实现:图片与视频混合展示的完整方案
  • 基于ERNIE 4.5的多智能体协作的自动化视频舆情分析报告生成器
  • 图像处理中的伪影
  • git新建项目如何推送到远程仓库
  • C#_面向对象设计的艺术
  • Python 网络编程实战指南:从 TCP_UDP 到 Socket 编程
  • 基于LangChain + Milvus 实现RAG
  • Linux学习-网络编程2
  • Zynq开发实践(fpga高频使用的两个场景)
  • Elasticsearch Rails 实战全指南(elasticsearch-rails / elasticsearch-model)
  • VLLM部署gpt-oss-20b踩坑记录
  • chrome driver在Mac上运行时提示安全问题怎么解决
  • STM32 - Embedded IDE - GCC - 重定向printf到串口
  • jmeter
  • [docker/大数据]Spark快速入门
  • DS 0 | 数据结构学习:前言