Factory — 一种创建型模式,将对象创建委托给工厂方法。在移动开发中,Factory Method 和 Abstract Factory 用于创建 ViewModel、NetworkClient、Repository 和其他依赖项。Factory 隔离了实例化逻辑,简化了实现的替换。更多信息 — 参见Refactoring Guru:Factory Method。
要点
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 中,这可以是协议中的 static method 或基类中的方法。在 Kotlin 中 — 带有工厂方法的 companion object 或抽象类中的 open fun。该模式广泛用于创建解析器、错误工厂和查询构建器。
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 实现。
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 — 用于创建相互关联或相互依赖的对象族而无需指定其具体类的模式。客户端使用抽象工厂接口,该接口定义了创建族中每个产品的方法。具体工厂实现接口并创建特定变体的对象。例如,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 Method | Abstract Factory |
|---|---|---|
| 产品数量 | 一个 | 族(多个) |
| 机制 | 继承(override) | 组合(protocol/interface) |
| iOS 示例 | PaymentFactory.create() | UIComponentFactory 用于 iOS/Android |
| Android 示例 | ViewModelProvider.Factory | ThemeFactory:创建按钮、文本、卡片 |
| 灵活性 | 简单的子类替换 | 完全替换整个族 |
实际案例 Android 中的 Abstract Factory — 通过统一的 DatabaseFactory 接口实现不同类型的数据库(SQLite vs Room)。工厂创建 DAO 对象、迁移和连接池。在 iOS 中 — 不同环境(Development/Staging/Production)的服务工厂。Abstract Factory 很少直接使用 — 其功能由 DI 容器(Dagger Module、Swinject Assembly)接管。
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 — 经典示例: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 适用于运行时动态选择实现(A/B 测试、功能开关、不同套餐的不同 API)。DI(Hilt、Dagger、Koin)更适合静态依赖 — 它自动创建和注入。Factory 和 DI 并不互斥:DI 可以在模块内部使用 Factory。
Factory 通过协议替换工厂来测试。在测试中创建实现相同协议并返回模拟对象的 TestFactory。对于静态 Factory 方法,测试更困难 — 需要 DI 容器或 swizzling。建议始终为 Factory 使用协议以保持可测试性。
ViewModelProvider.Factory — 来自 Jetpack 的接口,允许使用自定义参数创建 ViewModel。没有工厂时,ViewModel 通过反射创建并且只能有空的构造函数。Factory 接收参数(仓库、application context)并将它们传递给 ViewModel 的构造函数。Hilt 自动为 @HiltViewModel 生成 Factory。
Factory 实现了开闭原则(Open-Closed):系统对扩展开放(新实现添加到工厂),但对修改关闭(客户端代码不变)。添加新产品类型只需要修改工厂,而不是所有客户端。这是 Factory 相较于直接创建对象的关键优势。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。