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

抽象工厂模式

增加新的系列,工厂能够轻松扩展,而不需要大改生产线(原来的代码)。

efine _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<memory>
using namespace std;
//按钮接口:抽象产品
class Button
{
public:virtual void display() = 0;
};
//Spring按钮:具体产品
class SpringButton :public Button
{
public:void display(){cout << "显示绿色按钮" << endl;}
};
//Summer按钮类:
class SummerButton :public Button
{
public:void display(){cout << "显示蓝色按钮" << endl;}
};//文本框接口:抽象产品
class TextField
{
public:virtual void display() = 0;
};
//Spring文本框:具体产品
class SpringTextField :public TextField
{
public:void display(){cout << "显示绿色边文本框" << endl;}
};
//Summer文本框:具体产品
class SummerTextField :public TextField
{
public:void display(){cout << "显示蓝色边文本框" << endl;}
};
//界面皮肤工厂接口:抽象工厂
class SkinFactory
{
public://virtual Button* createButton() = 0;virtual std::unique_ptr<Button> createButton() = 0;//virtual TextField* createTextFiled() = 0;virtual std::unique_ptr<TextField> createTextField() = 0;
};
//Spring皮肤工厂:具体工厂
class SpringSkinFactory :public SkinFactory
{
public:std::unique_ptr<Button> createButton(){return std::make_unique<SpringButton>();}std::unique_ptr<TextField> createTextField(){return std::make_unique<SpringTextField>();}
};
class SummerSkinFactory :public SkinFactory
{
public:std::unique_ptr<Button> createButton(){return std::make_unique<SummerButton>();}std::unique_ptr<TextField> createTextField(){return std::make_unique<SummerTextField>();}
};
int main()
{std::unique_ptr<SkinFactory> factory = nullptr;std::unique_ptr<Button> bt = nullptr;std::unique_ptr<TextField> tf = nullptr;factory = std::make_unique<SummerSkinFactory>();bt = factory->createButton();tf = factory->createTextField();bt->display();tf->display();return 0;
}

象工厂模式(Abstract Factory Pattern)主要解决了以下几类问题:

1. 产品族创建的复杂性问题

  • 问题:当需要创建一组相互关联或依赖的产品对象时,直接实例化会导致客户端代码与具体类高度耦合

  • 解决:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类

2. 系统可扩展性问题

  • 问题:传统工厂方法在添加新产品族时需要修改大量代码

  • 解决:通过抽象工厂接口,可以轻松添加新的产品族(符合开闭原则)

3. 产品一致性要求问题

  • 问题:需要确保一组产品对象必须一起使用(如不同操作系统的UI控件不能混用)

  • 解决:工厂内部保证创建的产品属于同一产品族,客户端无法创建不匹配的产品组合

4. 多平台/多环境适配问题

  • 问题:同一套功能需要适配不同平台(如Windows/Mac的UI控件)

  • 解决:每个平台实现自己的具体工厂,客户端代码与平台无关

5. 对象创建与使用的耦合问题

  • 问题:客户端需要了解具体产品类的细节

  • 解决:客户端只与抽象接口交互,完全解耦具体实现

设计原则体现:

  1. 依赖倒置原则:客户端依赖抽象而非具体类

  2. 开闭原则:扩展新产品族无需修改现有代码

  3. 单一职责原则:每个工厂只负责创建特定产品族

  4. 里氏替换原则:具体工厂可替换抽象工厂

耦合(Coupling)

耦合 指的是代码模块之间的依赖关系。它衡量一个模块(类、函数、组件)对另一个模块的了解程度。

耦合的类型
  1. 紧耦合(High Coupling)

    • 模块之间高度依赖,修改一个模块可能影响多个其他模块。

    • 缺点:代码难以维护、扩展困难、测试复杂。

    • 例子

      class MySQLDatabase {
      public:void query() { /* MySQL 查询逻辑 */ }
      };class UserService {
      private:MySQLDatabase db;  // 直接依赖 MySQLDatabase
      public:void getUser() { db.query(); }
      };
      • UserService 直接依赖 MySQLDatabase,如果要换成 PostgreSQL,必须修改 UserService

  2. 松耦合(Low Coupling)

    • 模块之间依赖接口或抽象,而不是具体实现。

    • 优点:易于扩展、维护、测试。

    • 例子

      class Database {
      public:virtual void query() = 0;
      };class MySQLDatabase : public Database {
      public:void query() override { /* MySQL 查询逻辑 */ }
      };class PostgreSQLDatabase : public Database {
      public:void query() override { /* PostgreSQL 查询逻辑 */ }
      };class UserService {
      private:Database* db;  // 依赖抽象,而不是具体实现
      public:UserService(Database* db) : db(db) {}void getUser() { db->query(); }
      };
      • UserService 只依赖 Database 接口,可以轻松切换不同的数据库实现。


开闭原则(Open/Closed Principle, OCP)

开闭原则 是 SOLID 设计原则 之一,由 Bertrand Meyer 提出,核心思想:

"软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。"

含义
  1. 对扩展开放(Open for Extension)

    • 允许在不修改现有代码的情况下,通过 继承、组合、接口实现 等方式扩展功能。

  2. 对修改关闭(Closed for Modification)

    • 已有的核心代码(如接口、抽象类)不应被频繁修改,避免引入新 Bug。

如何实现开闭原则?
  • 使用抽象(接口/基类),让具体实现可扩展。

  • 依赖注入(Dependency Injection, DI),避免硬编码依赖。

  • 策略模式、工厂模式 等设计模式帮助解耦。

例子

违反 OCP 的情况

class PaymentProcessor {
public:void processPayment(string type) {if (type == "credit") {// 处理信用卡支付} else if (type == "paypal") {// 处理 PayPal 支付}// 如果要新增支付方式,必须修改这个类}
};
  • 每次新增支付方式都要修改 processPayment,违反 OCP。

符合 OCP 的情况

class PaymentMethod {
public:virtual void pay() = 0;
};class CreditCardPayment : public PaymentMethod {
public:void pay() override { /* 信用卡支付逻辑 */ }
};class PayPalPayment : public PaymentMethod {
public:void pay() override { /* PayPal 支付逻辑 */ }
};class PaymentProcessor {
public:void processPayment(PaymentMethod* method) {method->pay();  // 依赖抽象,支持扩展}
};
  • 新增支付方式只需继承 PaymentMethod,无需修改 PaymentProcessor


耦合 vs. 开闭原则的关系

概念耦合开闭原则
目标降低模块间的依赖使代码易于扩展,避免修改已有代码
实现方式依赖抽象(接口)依赖抽象(接口)
关联松耦合的代码更容易符合开闭原则

总结

  • 耦合 衡量代码模块之间的依赖程度,松耦合 是良好设计的关键。

  • 开闭原则 强调 扩展开放,修改关闭,避免频繁修改核心代码。

  • 两者结合:通过 抽象、接口、设计模式 实现松耦合,使代码更易扩展和维护。

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

相关文章:

  • 视觉图像处理中级篇 [2]—— 外观检查 / 伤痕模式的原理与优化设置方法
  • 中宇联:以“智云融合+AI”赋能全栈云MSP服务,深化阿里云生态合作
  • 【大模型理论篇】混合思考之自适应思维链
  • Kubernetes架构概览
  • MySQL转PostgreSQL迁移实战:从语法错误到完美兼容
  • spring cloud ——gateway网关
  • 嵌入式系统常用架构
  • 【02】大恒相机SDK C#开发 —— 初始化相机,采集第一帧图像
  • 如何使用一台电脑adb调试多个Android设备
  • vue+elementUI上传图片至七牛云组件封装及循环使用
  • 【机器学习】KNN算法与模型评估调优
  • 蓝牙 BR/EDR 与 BLE PHY
  • 告别物业思维:科技正重构产业园区的价值坐标系
  • 微信小程序中进行参数传递的方法
  • 基于Spring Boot实现中医医学处方管理实践
  • 【数据结构】算法代码
  • 将开发的软件安装到手机:环境配置、android studio设置、命令行操作
  • Coze Studio:开源AI Agent开发工具的全方位实践指南
  • Rust视频处理开源项目精选
  • 电商数据采集 API 接口:开启数据驱动业务的新引擎
  • Android依赖注入框架Hilt入门指南
  • 深度学习:损失函数Loss Function
  • Android 基础入门学习目录(持续更新)
  • Java 大视界 -- Java 大数据在智能交通公交客流预测与线路优化中的深度实践(15 城验证,年省 2.1 亿)(373)
  • 软件项目中如何编写项目计划书?指南
  • Linux日志管理与时间同步
  • 468. 验证IP地址
  • 【JavaEE】(7) 网络原理 TCP/IP 协议
  • Git踩坑
  • imx6ull-驱动开发篇5——新字符设备驱动实验