商洛市网站建设_网站建设公司_ASP.NET_seo优化
2025/12/20 20:48:11 网站建设 项目流程

1. 核心维度的区别

我们可以从两个维度来看待这个问题:

维度 工厂方法模式 (Factory Method) 抽象工厂模式 (Abstract Factory)
产品数量 单一产品 产品族 (Product Family)
接口方法 只有一个 Create() 方法 有多个方法 CreateA(), CreateB()...
关注点 只要把对象造出来就行,不需要考虑搭配 必须保证造出来的一堆对象是配套的,不能混用
维度举例 比如:只生产“枪” 比如:生产“枪” + “子弹” + “瞄准镜”
复杂度 较低 较高

2. 生动的比喻

A. 工厂方法模式 (Factory Method)

就像“单一品牌的专卖店”,但只卖一样东西

  • 需求: 你想买辆车。
  • 奔驰工厂: 只负责造 奔驰车
  • 宝马工厂: 只负责造 宝马车
  • 客户端: 你找奔驰工厂,只能拿到奔驰车,拿不到别的。

B. 抽象工厂模式 (Abstract Factory)

就像“品牌全家桶”或者“套装装备”

  • 需求: 你不仅要买车,还要配套的钥匙、配套的轮胎。
  • 奔驰工厂: 负责造 奔驰车 + 奔驰钥匙 + 奔驰轮胎
  • 宝马工厂: 负责造 宝马车 + 宝马钥匙 + 宝马轮胎
  • 客户端: 你找奔驰工厂,它会给你一整套奔驰的东西。
  • 约束: 你绝对不会从奔驰工厂里拿到“宝马的钥匙”。(这就是抽象工厂的核心价值:防止混搭)

3. 代码结构的直观对比

工厂方法 (Factory Method)

接口里只有一个函数,生产一种东西。

class ICarFactory {
public:// 只有一个 Createvirtual ICar* CreateCar() = 0; 
};// 具体工厂
class BenzFactory : public ICarFactory {ICar* CreateCar() override { return new BenzCar(); }
};

抽象工厂 (Abstract Factory)

接口里有一组函数,生产一系列相关的东西。

class ICarSuiteFactory {
public:// 有一组 Create,它们是配套的virtual ICar* CreateCar() = 0;virtual IKey* CreateKey() = 0;virtual ITire* CreateTire() = 0;
};// 具体工厂
class BenzSuiteFactory : public ICarSuiteFactory {ICar* CreateCar()  override { return new BenzCar(); }IKey* CreateKey()  override { return new BenzKey(); } // 必须是奔驰钥匙ITire* CreateTire() override { return new BenzTire(); } // 必须是奔驰轮胎
};

4. 扩展性的区别 (开闭原则 OCP 的不同侧重)

这是最让架构师头疼的地方,两者的优缺点是互补的:

A. 工厂方法模式

  • 增加新品牌(如奥迪): 非常容易。写一个 AudiCarAudiFactory 即可。符合 OCP。
  • 增加新产品(如造卡车): 需要新建一套接口。因为原来的工厂只造轿车。

B. 抽象工厂模式

  • 增加新系列(如奥迪系列): 非常容易。写一个 AudiSuiteFactory,里面造奥迪车、奥迪钥匙。符合 OCP。
  • 增加新产品(如增加“方向盘”): 非常痛苦(灾难级)
    • 你需要修改 ICarSuiteFactory 接口,增加 CreateSteeringWheel()
    • 后果: 所有的具体工厂(奔驰工厂、宝马工厂...)全部都要修改代码来实现这个新函数。这严重违反了开闭原则。

总结:如何选择?

  1. 问自己:我需要创建的对象,是“孤立”的,还是“成套”的?
    • 如果只是创建一个 Logger,或者一个 ThreadPool,用 工厂方法
    • 如果需要创建 GUI 皮肤(按钮+背景+滚动条必须风格一致),或者数据库组件(Connection+Command+Result必须全是 MySQL 的),用 抽象工厂
  2. 大多数情况下,工厂方法模式就够用了。 抽象工厂由于太重,且接口难以修改,只有在确实有“产品族约束”时才使用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询