Factory:Factory Method 和 Abstract Factory 模式的本质

作者: IT Sectr 发布日期: 2026-02-17 阅读时间: 7 分钟

Factory — 一种创建型模式,将对象创建委托给工厂方法。在移动开发中,Factory Method 和 Abstract Factory 用于创建 ViewModel、NetworkClient、Repository 和其他依赖项。Factory 隔离了实例化逻辑,简化了实现的替换。更多信息 — 参见Refactoring Guru:Factory Method

要点

  • Factory — 无需指定具体类即可创建对象的创建型模式
  • Factory Method — 超类中的方法,在子类中重写以创建对象
  • Abstract Factory — 用于创建相互关联的对象族的接口
  • 测试 — 工厂简化了测试中用模拟对象替换实现的过程
  • DI vs Factory — 依赖注入在现代应用程序中取代了工厂

什么是 Factory:对象创建模式的本质?

Factory — 来自 GoF 目录的创建型设计模式。主要思想:将对象创建逻辑从客户端代码移到单独的方法或类中。客户端使用接口或抽象类,具体实现由工厂创建。这实现了依赖倒置原则(Dependency Inversion):客户端不依赖于具体类,只依赖于抽象。

两种变体Factory:Factory Method 和 Abstract Factory。Factory Method — 类中的一个方法,子类重写该方法以创建对象。Abstract Factory — 带有工厂方法族的接口,用于创建相互关联的对象组。两种变体解决同一个问题:客户端不直接调用 new MyClass(),而是请求工厂根据其类型或参数创建对象。

Factory vs new() — 直接创建对象将代码与具体实现紧密耦合。Factory 添加了一个中间层:更改实现只需要修改工厂,而无需修改所有客户端。在移动开发中,Factory 被广泛用于创建 ViewModel(ViewModelProvider.Factory)、网络客户端(Retrofit.create())、列表适配器和序列化工厂。DI 容器(Dagger、Koin)自动生成工厂。

Factory Method:Swift 和 Kotlin 示例

Factory Method — 在协议或抽象类中声明的返回特定类型对象的方法。子类实现此方法,创建具体实例。在 Swift 中,这可以是协议中的 static method 或基类中的方法。在 Kotlin 中 — 带有工厂方法的 companion object 或抽象类中的 open fun。该模式广泛用于创建解析器、错误工厂和查询构建器。

swift
protocol PaymentGateway {
    func processPayment(amount: Decimal) async throws -> PaymentResult
}

final class StripeGateway: PaymentGateway { /* ... */ }
final class ApplePayGateway: PaymentGateway { /* ... */ }

enum PaymentType { case stripe, applePay }

final class PaymentFactory {
    // Factory Method
    static func create(type: PaymentType) -> PaymentGateway {
        switch type {
        case .stripe: return StripeGateway()
        case .applePay: return ApplePayGateway()
        }
    }
}

// 使用
let gateway = PaymentFactory.create(type: .stripe)

Kotlin 版本 Factory Method 使用 companion object 或 sealed class 来限制类型。Sealed class 保证 when 分支覆盖所有可能的类型 — 编译器检查完整性。这在 Android 项目中很典型,工厂根据 build flavour 或配置创建不同的 Repository 或 DataSource 实现。

kotlin
sealed class PaymentType {
    object Stripe : PaymentType()
    object ApplePay : PaymentType()
}

interface PaymentGateway {
    suspend fun processPayment(amount: BigDecimal): PaymentResult
}

class PaymentFactory {
    companion object {
        fun create(type: PaymentType): PaymentGateway = when (type) {
            PaymentType.Stripe -> StripeGateway()
            PaymentType.ApplePay -> ApplePayGateway()
        }
    }
}

Abstract Factory:相互关联的对象族

Abstract Factory — 用于创建相互关联或相互依赖的对象族而无需指定其具体类的模式。客户端使用抽象工厂接口,该接口定义了创建族中每个产品的方法。具体工厂实现接口并创建特定变体的对象。例如,iOS 的 UI 组件工厂创建 UIButton、UILabel、UITableView,而 Android 的则创建 Button、TextView、RecyclerView。

Abstract Factory vs Factory Method — Factory Method 通过继承创建单一类型的对象,Abstract Factory 通过组合创建对象族。Factory Method 在子类中重写,Abstract Factory 通过协议提供多个工厂方法。Abstract Factory 通常包含多个 Factory Method。在移动开发中,Abstract Factory 用于平台相关组件、主题和数据库工厂。

特征Factory MethodAbstract Factory
产品数量一个族(多个)
机制继承(override)组合(protocol/interface)
iOS 示例PaymentFactory.create()UIComponentFactory 用于 iOS/Android
Android 示例ViewModelProvider.FactoryThemeFactory:创建按钮、文本、卡片
灵活性简单的子类替换完全替换整个族

实际案例 Android 中的 Abstract Factory — 通过统一的 DatabaseFactory 接口实现不同类型的数据库(SQLite vs Room)。工厂创建 DAO 对象、迁移和连接池。在 iOS 中 — 不同环境(Development/Staging/Production)的服务工厂。Abstract Factory 很少直接使用 — 其功能由 DI 容器(Dagger Module、Swinject Assembly)接管。

iOS 中的 Factory:协议和静态方法

Swift Factory 通过协议和静态方法实现。Factory 协议声明返回抽象类型的 create() 方法。具体工厂实现协议并创建所需的对象。对于简单情况,Swift 不需要单独的工厂类 — enum 或 struct 中的静态方法就足够了。对于复杂场景,使用通过 DI 注入的 Factory 协议。

iOS SDK 中的 Factory — 许多系统工厂:UIStoryboard.instantiateViewController(withIdentifier:)、NSKeyedUnarchiver.unarchivedObject(ofClass:from:)、JSONDecoder().decode(_:from:)。开发人员为 ViewController(StoryboardFactory)、服务(ServiceFactory)和数据模型创建工厂。Factory Method 在 VIPER 和 Clean Swift 架构中用于创建屏幕模块。

Factory + DI — 现代替代方案:DI 容器(Swinject、Factory)自动为注册的类型生成工厂。容器存储对象创建配方并解析依赖关系。Factory 库(github.com/hmlongco/Factory)使用 @Injected(.service) 进行自动注入。DI 工厂通过一行代码替换整个模块来进行测试:container.register { MockService() }。

Android 中的 Factory:companion factory 和 DI 模块

Android Factory — 经典示例:ViewModelProvider.Factory 用于创建带参数的 ViewModel。Google 建议使用 Hilt 自动生成 ViewModel 工厂 — @HiltViewModel 注解自动创建 Factory。对于简单对象,使用带有 create() 或 invoke() 方法的 companion object。在 Kotlin 中,invoke 运算符允许像函数一样调用工厂:Factory(param)。

Jetpack Compose 中的 Factory — 工厂用于创建状态和效果。remember { Factory.create() } 在首次渲染时创建对象并在 composable 的整个生命周期内保留它。Compose 中的 ViewModel 通过 viewModel() 创建 — 这是由 Hilt 管理的工厂。在 Compose 中,工厂较少显式出现,因为 DI 和 Compose StateManager 接管了对象创建。

Factory vs Hilt — Dagger/Hilt 在编译阶段自动生成工厂。@Module + @Provides 取代 Factory Method,@Binds 取代 Abstract Factory。手动工厂在运行时动态选择实现(A/B 测试、功能开关)时仍然适用。对于静态依赖,Hilt 完全自动化了对象创建 — 开发人员只需编写接口和注解。

常见问题

Factory Method 和 Abstract Factory 有什么区别?

Factory Method 通过继承创建单一类型的对象 — 子类重写工厂方法。Abstract Factory 通过组合创建对象族 — 工厂接口为多个产品声明方法。Factory Method 更简单,Abstract Factory 对于平台相关或主题组件更灵活。

什么时候使用 Factory 而不是 DI?

Factory 适用于运行时动态选择实现(A/B 测试、功能开关、不同套餐的不同 API)。DI(Hilt、Dagger、Koin)更适合静态依赖 — 它自动创建和注入。Factory 和 DI 并不互斥:DI 可以在模块内部使用 Factory。

如何测试使用 Factory 的代码?

Factory 通过协议替换工厂来测试。在测试中创建实现相同协议并返回模拟对象的 TestFactory。对于静态 Factory 方法,测试更困难 — 需要 DI 容器或 swizzling。建议始终为 Factory 使用协议以保持可测试性。

Android 中的 ViewModelProvider.Factory 是什么?

ViewModelProvider.Factory — 来自 Jetpack 的接口,允许使用自定义参数创建 ViewModel。没有工厂时,ViewModel 通过反射创建并且只能有空的构造函数。Factory 接收参数(仓库、application context)并将它们传递给 ViewModel 的构造函数。Hilt 自动为 @HiltViewModel 生成 Factory。

Factory 如何与开闭原则相关?

Factory 实现了开闭原则(Open-Closed):系统对扩展开放(新实现添加到工厂),但对修改关闭(客户端代码不变)。添加新产品类型只需要修改工厂,而不是所有客户端。这是 Factory 相较于直接创建对象的关键优势。

总结

  • Factory — 通过抽象创建对象的创建型模式
  • Factory Method — 在子类中重写的一个方法
  • Abstract Factory — 用于创建对象族的接口
  • iOS — 用于工厂的协议和静态方法
  • Android — companion object、ViewModelProvider.Factory、Hilt
  • DI vs Factory — DI 自动创建,Factory 用于动态选择
  • 测试 — Factory 协议是替换实现的必要条件

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读