抽象工厂模式

简介: 抽象工厂模式是一种创建型设计模式,提供接口用于创建一系列相关或依赖的对象,无需指定具体类。适用于产品族的创建,确保兼容性和一致性。优点包括分离接口与实现、产品族一致性、遵循开闭原则;缺点是扩展产品种类困难、增加系统复杂性。常见应用场景包括跨平台 UI、数据库访问、游戏开发和主题风格切换。

抽象工厂模式详解

定义

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。

抽象工厂模式特别适合产品族的创建,保证产品的兼容性和一致性。


抽象工厂模式的特点

优点

  1. 分离接口与实现:客户端仅依赖抽象接口,与具体实现解耦。
  2. 产品族一致性:确保同一工厂创建的对象是兼容的,避免出现不匹配的情况。
  3. 遵循开闭原则:添加新产品族时,只需新增具体工厂类,无需修改已有代码。

缺点

  1. 扩展产品种类困难:新增产品种类时,需要修改抽象工厂接口及所有子类。
  2. 增加系统复杂性:引入额外的抽象层,使系统的类结构更加复杂。

适用场景

  1. 跨平台应用开发
    通过抽象工厂为不同操作系统(Windows、Mac、Linux)创建平台相关的 UI 控件。
  2. 数据库访问
    支持不同数据库(MySQL、Oracle、SQL Server)的数据访问逻辑。
  3. 游戏开发
    在游戏中为不同种族或阵营创建一系列相关的角色和武器。
  4. 主题风格切换
    应用支持切换不同主题,每个主题有一组对应的按钮、窗口样式。

抽象工厂模式的结构

核心角色

  1. 抽象工厂(Abstract Factory):定义创建一系列相关或相互依赖对象的接口。
  2. 具体工厂(Concrete Factory):实现抽象工厂接口,创建特定产品族的对象。
  3. 抽象产品(Abstract Product):为每种产品定义一个接口。
  4. 具体产品(Concrete Product):实现抽象产品接口,由具体工厂创建。

使用案例

案例 1:跨平台 UI

根据操作系统不同,创建适配的按钮和窗口。

案例 2:数据库访问

创建针对不同数据库的连接对象和查询对象。

案例 3:游戏装备

为不同阵营创建特定类型的武器、护甲等装备。


抽象工厂模式的实现

C++ 实现

#include <iostream>
#include <memory>

// 抽象产品 A
class Button {
public:
   virtual void click() = 0;
   virtual ~Button() = default;
};

// 抽象产品 B
class Window {
public:
   virtual void render() = 0;
   virtual ~Window() = default;
};

// 具体产品 A1
class WindowsButton : public Button {
public:
   void click() override {
       std::cout << "Windows Button Clicked!" << std::endl;
   }
};

// 具体产品 A2
class MacButton : public Button {
public:
   void click() override {
       std::cout << "Mac Button Clicked!" << std::endl;
   }
};

// 具体产品 B1
class WindowsWindow : public Window {
public:
   void render() override {
       std::cout << "Rendering Windows Window!" << std::endl;
   }
};

// 具体产品 B2
class MacWindow : public Window {
public:
   void render() override {
       std::cout << "Rendering Mac Window!" << std::endl;
   }
};

// 抽象工厂
class GUIFactory {
public:
   virtual std::unique_ptr<Button> createButton() = 0;
   virtual std::unique_ptr<Window> createWindow() = 0;
   virtual ~GUIFactory() = default;
};

// 具体工厂 1
class WindowsFactory : public GUIFactory {
public:
   std::unique_ptr<Button> createButton() override {
       return std::make_unique<WindowsButton>();
   }
   std::unique_ptr<Window> createWindow() override {
       return std::make_unique<WindowsWindow>();
   }
};

// 具体工厂 2
class MacFactory : public GUIFactory {
public:
   std::unique_ptr<Button> createButton() override {
       return std::make_unique<MacButton>();
   }
   std::unique_ptr<Window> createWindow() override {
       return std::make_unique<MacWindow>();
   }
};

// 客户端代码
int main() {
   std::unique_ptr<GUIFactory> factory = std::make_unique<WindowsFactory>();
   auto button = factory->createButton();
   auto window = factory->createWindow();

   button->click();
   window->render();

   factory = std::make_unique<MacFactory>();
   button = factory->createButton();
   window = factory->createWindow();

   button->click();
   window->render();

   return 0;
}


C# 实现

using System;

// 抽象产品 A
public abstract class Button {
   public abstract void Click();
}

// 抽象产品 B
public abstract class Window {
   public abstract void Render();
}

// 具体产品 A1
public class WindowsButton : Button {
   public override void Click() {
       Console.WriteLine("Windows Button Clicked!");
   }
}

// 具体产品 A2
public class MacButton : Button {
   public override void Click() {
       Console.WriteLine("Mac Button Clicked!");
   }
}

// 具体产品 B1
public class WindowsWindow : Window {
   public override void Render() {
       Console.WriteLine("Rendering Windows Window!");
   }
}

// 具体产品 B2
public class MacWindow : Window {
   public override void Render() {
       Console.WriteLine("Rendering Mac Window!");
   }
}

// 抽象工厂
public abstract class GUIFactory {
   public abstract Button CreateButton();
   public abstract Window CreateWindow();
}

// 具体工厂 1
public class WindowsFactory : GUIFactory {
   public override Button CreateButton() {
       return new WindowsButton();
   }

   public override Window CreateWindow() {
       return new WindowsWindow();
   }
}

// 具体工厂 2
public class MacFactory : GUIFactory {
   public override Button CreateButton() {
       return new MacButton();
   }

   public override Window CreateWindow() {
       return new MacWindow();
   }
}

// 客户端代码
class Program {
   static void Main(string[] args) {
       GUIFactory factory = new WindowsFactory();
       Button button = factory.CreateButton();
       Window window = factory.CreateWindow();

       button.Click();
       window.Render();

       factory = new MacFactory();
       button = factory.CreateButton();
       window = factory.CreateWindow();

       button.Click();
       window.Render();
   }
}


抽象工厂模式的类图

扩展与对比

1. 抽象工厂 vs 工厂方法

特性 工厂方法模式 抽象工厂模式
关注点 单一产品的创建 产品族的创建
扩展性 添加新产品需新增具体工厂类 添加新产品族需新增抽象工厂及实现
复杂度 较低 较高

2. 抽象工厂扩展

  • 结合单例模式:避免频繁创建工厂实例。
  • 结合建造者模式:处理复杂产品的构建细节。

总结

抽象工厂模式非常适合产品族场景,能很好地保证产品间的兼容性。但在产品种类频繁变化的情况下,其扩展性受到限制。通过结合其他模式(如单例、建造者),可以进一步提升其灵活性和实用性。

相关文章
|
11月前
|
设计模式 C# C++
适配器模式(Adapter Pattern)
适配器模式是一种结构型设计模式,通过将一个类的接口转换为客户期望的另一个接口,使原本接口不兼容的类可以一起工作。它包括目标接口、适配者和适配器三个核心角色。适配器模式常用于解决旧系统兼容性问题、第三方库整合和统一接口等场景。该模式有类适配器和对象适配器两种实现方式,分别通过继承和组合实现。适配器模式的优点包括提高兼容性、遵循开闭原则和灵活性高,但也存在适配器数量增加导致复杂性和可能影响性能的缺点。
|
11月前
|
设计模式 安全 C#
单例模式详解
单例模式是一种常用的创建型设计模式,确保某个类只有一个实例,并提供一个全局访问点。本文详细介绍了单例模式的定义、特点、适用场景、优缺点及实现代码(C++ 和 C#),并探讨了线程安全的实现细节和与依赖注入的结合使用。
|
11月前
|
设计模式 IDE 数据可视化
UML中类图的介绍与使用
类图是 UML 中用于展示系统静态结构的重要工具,包括类、接口及其关系。类图有助于系统可视化、团队沟通、发现设计问题、文档化系统和辅助开发工具。类图的三大元素是类、接口和关系,其中关系又细分为关联、聚合、组合、继承、实现和依赖。类图在设计模式学习和实际开发中非常重要,许多现代 IDE 都支持从类图生成代码或从代码生成类图。
|
11月前
|
传感器 安全
第四问:QT中信号和槽原理
Qt的信号与槽机制是观察者模式的典型实现,允许对象间通信而不直接依赖。信号用于通知事件发生,槽是响应信号的函数,通过`QObject::connect()`连接。这种机制实现了松耦合、灵活扩展和自动通知,适用于UI更新和数据绑定等场景。
|
11月前
|
XML 设计模式 JSON
模板方法模式(Template Method Pattern)
模板方法模式是一种行为型设计模式,定义一个操作中的算法骨架,将某些步骤的实现延迟到子类。子类可以在不改变算法结构的情况下重新定义算法的某些步骤。适用于多个类有相似操作流程且部分步骤需要定制的场景。优点包括高复用性、扩展性强和清晰明确;缺点是灵活性降低和可能引入性能开销。示例包括文件解析和策略模式的对比。
模板方法模式(Template Method Pattern)
|
11月前
|
存储 缓存 网络协议
第五问:一个程序从点击到启动发生了什么?
一个可执行程序从用户点击启动到运行,经历了8个主要阶段:用户触发启动、操作系统查找文件、进程创建、可执行文件加载到内存、初始化程序上下文、执行程序入口点、程序运行和程序退出。涉及硬盘、内存、缓存等硬件交互。
|
11月前
|
安全 网络安全 数据安全/隐私保护
第六问:http和https区别与联系
HTTP 和 HTTPS 是现代网络通信中的两种重要协议。HTTP 是明文传输协议,无加密功能;HTTPS 在 HTTP 基础上加入 SSL/TLS 加密层,提供数据加密、身份验证和数据完整性保障。HTTP 适用于非敏感信息传输,如新闻网站;HTTPS 适用于在线支付、账户登录等需要保护用户数据的场景。
|
11月前
|
存储 设计模式 算法
命令模式(Command Pattern)
命令模式是一种行为型设计模式,将请求封装为对象,实现参数化请求、支持撤销操作和记录日志。适用于需要解耦发送者和接收者的场景,如智能家居系统中的遥控器控制电灯开关并支持撤销功能。优点包括解耦、支持撤销与恢复操作,但过度使用会增加系统复杂度。
|
11月前
|
设计模式 监控 数据库
代理模式(Proxy Pattern)
代理模式(Proxy Pattern)是一种设计模式,通过一个中间对象(代理)来间接访问目标对象,以控制访问权限或添加额外功能。常见的代理类型包括远程代理、虚拟代理、保护代理和智能引用代理。代理模式常用于延迟加载、权限控制、日志记录等场景,能够提高系统的灵活性和安全性。
|
11月前
|
设计模式 C# C++
责任链模式(Chain of Responsibility Pattern)
责任链模式是一种行为型设计模式,允许多个对象按顺序处理请求,直到某个对象处理为止。适用于多个对象可能处理同一请求的场景,如请假审批流程。优点是灵活性高、降低耦合,但责任链过长可能影响性能。