Skip to content

工厂模式和抽象工厂模式有什么区别? ​

  • 标签:设计模式

🏛 业务架构师 ​

区别一句话:工厂模式创建"一个产品等级结构"里的产品(同族类的不同实现),抽象工厂创建"一个产品族"(跨品类的配套组合)。

用业务说话最清楚——电商多渠道履约场景:

  • 工厂模式:物流商选择。产品是"物流能力"这一个维度:顺丰、圆通、京东各是一个实现,LogisticsFactory.create("SF")。单一维度的变化;
  • 抽象工厂:跨境多站点开店。每个站点要一整套配套对象——支付网关 + 物流商 + 发票规则 + 文案语言。AmazonFactory 一套、ShopeeFactory 一套,工厂内部保证"同一站点的所有组件互相匹配"。变化是"一套规则体系"的整体切换。

我的判断标准:变化的单位是"个"还是"套"。组件间没有配套约束,各自独立选型(支付选 A、物流选 B 也合法),用工厂/策略就够了;组件必须成套出现、错配就是业务事故(比如日本站点开了欧盟的发票规则,税务合规风险),才值得抽象工厂。

真实教训:见过团队给"四种通知渠道×三种模板"硬上抽象工厂,12 个组合类,后来模板改个字段要动六个类——没有"成套约束"的抽象工厂是纯粹的过度设计。反过来,站点扩张到第五个时抽象工厂的优势才真正兑现:新增一个工厂类,全部组件本地化一次到位。模式选型错了,代价在未来每一次需求变更时复利收取。

🏗 系统架构师 ​

两者都是创建型模式,差异在"产品的组织维度":

  • 工厂方法:一个工厂接口对应一个产品等级(一种抽象产品),每个具体工厂造一种具体产品。加产品 = 加一对(产品类 + 工厂类),符合开闭原则;
  • 抽象工厂:一个工厂造一族产品(多个有关联的抽象产品),比如 DatabaseFactory 同时造 Connection、Statement、ResultSet;UIFactory 同时造 Button、TextBox。加产品族 = 加一个工厂,轻松;加新产品等级 = 所有工厂都要改,违背开闭。

我按场景选:

  • 产品单一维度、扩展以"新增种类"为主 → 工厂方法(或退化为简单工厂 + Spring Map 注入);
  • 产品天然成族、切换要整体一致(换数据库整族换、换主题整族换、多渠道支付整套能力)→ 抽象工厂,保证族内产品兼容性由工厂统一约束。

实际工程:Java JDBC(Connection 就是抽象工厂)、Spring 的 ConnectionFactory、跨云厂商 SDK 的多产品客户端都是抽象工厂。一个判断口诀:"加族易"选抽象工厂,"加类易"选工厂方法,先问业务未来哪种变化方向更频繁。

💻 全栈开发专家 ​

工厂方法生产"一种产品",抽象工厂生产"一个产品族"(多个相关产品的组合)。

java
// 工厂方法:一个工厂对应一个产品
interface PayFactory { PayChannel create(); }
class AlipayFactory implements PayFactory { public PayChannel create() { return new AlipayChannel(); } }

// 抽象工厂:一个工厂负责一族相关产品
interface CloudFactory {
    Compute createCompute();
    Storage createStorage();
}
class AwsFactory implements CloudFactory { ... }   // AWS 全家桶
class AliyunFactory implements CloudFactory { ... } // 阿里云全家桶

判断标准:产品之间有没有"配套关系"。支付渠道和优惠计算如果按渠道配套出现(支付宝配套活动 A、微信配套活动 B),就值得抽象工厂;各维度独立扩展就工厂方法。

实际工程里我用抽象工厂的场景:多租户/多云适配层(同一套业务代码,切换基础设施供应商时整族替换)、报表导出(Excel 族:样式器+单元格渲染器+导出器)。

务实提醒:抽象工厂每加一个新产品类型(比如 CloudFactory 加 Network),所有工厂实现都要改——扩展产品族容易、扩展产品类型难。代码里更常见的是"工厂方法 + 依赖注入"的组合,Spring 容器本身就充当了超级工厂,我不会为了模式完整性硬凑类爆炸的抽象工厂。