Factory — một mẫu tạo đối tượng, ủy quyền việc tạo đối tượng cho các phương thức factory. Trong phát triển di động, Factory Method và Abstract Factory được sử dụng để tạo ViewModel, NetworkClient, Repository và các phụ thuộc khác. Factory cô lập logic khởi tạo, đơn giản hóa việc thay thế các triển khai. Chi tiết thêm — tại Refactoring Guru: Factory Method.
Những điểm chính
Factory — một mẫu thiết kế tạo đối tượng từ danh mục GoF. Ý tưởng chính: chuyển logic tạo đối tượng khỏi mã khách hàng vào một phương thức hoặc lớp riêng biệt. Khách hàng làm việc với một giao diện hoặc lớp trừu tượng, trong khi triển khai cụ thể được tạo bởi factory. Điều này thực hiện nguyên tắc Đảo ngược Phụ thuộc: khách hàng không phụ thuộc vào các lớp cụ thể, chỉ phụ thuộc vào các trừu tượng.
Hai biến thể của Factory: Factory Method và Abstract Factory. Factory Method — một phương thức duy nhất trong lớp mà các lớp con ghi đè để tạo đối tượng. Abstract Factory — một giao diện với một họ các phương thức factory để tạo nhóm các đối tượng liên quan. Cả hai biến thể đều giải quyết cùng một vấn đề: khách hàng không gọi new MyClass() trực tiếp, mà yêu cầu factory tạo đối tượng theo loại hoặc tham số của nó.
Factory vs new() — việc tạo đối tượng trực tiếp gắn chặt mã với một triển khai cụ thể. Factory thêm một lớp: thay đổi triển khai chỉ yêu cầu chỉnh sửa factory, không phải tất cả khách hàng. Trong phát triển di động, Factory được sử dụng tích cực để tạo ViewModel (ViewModelProvider.Factory), máy khách mạng (Retrofit.create()), bộ chuyển đổi danh sách và factory tuần tự hóa. Các vùng chứa DI (Dagger, Koin) tự động tạo factory.
Factory Method — một phương thức được khai báo trong giao thức hoặc lớp trừu tượng, trả về một đối tượng của một loại cụ thể. Các lớp con triển khai phương thức, tạo ra các thể hiện cụ thể. Trong Swift, nó có thể là phương thức tĩnh trong giao thức hoặc phương thức trong lớp cơ sở. Trong Kotlin — companion object với phương thức factory hoặc open fun trong lớp trừu tượng. Mẫu này được sử dụng rộng rãi để tạo trình phân tích cú pháp, factory lỗi và trình xây dựng truy vấn.
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()
}
}
}
// Sử dụng
let gateway = PaymentFactory.create(type: .stripe)
Phiên bản Kotlin của Factory Method sử dụng companion object hoặc sealed class để giới hạn loại. Sealed class đảm bảo rằng nhánh when bao phủ tất cả các loại có thể — trình biên dịch kiểm tra tính đầy đủ. Điều này điển hình cho các dự án Android nơi factory tạo các triển khai Repository hoặc DataSource khác nhau tùy theo build flavour hoặc cấu hình.
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 — một mẫu để tạo họ các đối tượng liên quan hoặc phụ thuộc lẫn nhau mà không chỉ định các lớp cụ thể của chúng. Khách hàng làm việc với giao diện factory trừu tượng, định nghĩa các phương thức để tạo từng sản phẩm của họ. Một factory cụ thể triển khai giao diện và tạo các đối tượng của một biến thể cụ thể. Ví dụ, factory thành phần UI cho iOS tạo UIButton, UILabel, UITableView, trong khi cho Android — Button, TextView, RecyclerView.
Abstract Factory vs Factory Method — Factory Method tạo một loại đối tượng thông qua kế thừa, Abstract Factory tạo một họ đối tượng thông qua hợp thành. Factory Method được ghi đè trong các lớp con, Abstract Factory cung cấp nhiều phương thức factory thông qua một giao thức. Abstract Factory thường chứa nhiều Factory Method. Trong phát triển di động, Abstract Factory được sử dụng cho các thành phần phụ thuộc nền tảng, thiết kế chủ đề và factory cơ sở dữ liệu.
| Đặc điểm | Factory Method | Abstract Factory |
|---|---|---|
| Số lượng sản phẩm | Một | Họ (nhiều) |
| Cơ chế | Kế thừa (override) | Hợp thành (giao thức/giao diện) |
| Ví dụ iOS | PaymentFactory.create() | UIComponentFactory cho iOS/Android |
| Ví dụ Android | ViewModelProvider.Factory | ThemeFactory: tạo nút, văn bản, thẻ |
| Linh hoạt | Thay thế lớp con đơn giản | Thay thế toàn bộ họ |
Trường hợp thực tế của Abstract Factory trong Android — triển khai các loại cơ sở dữ liệu khác nhau (SQLite vs Room) thông qua một giao diện DatabaseFactory duy nhất. Factory tạo các đối tượng DAO, di chuyển và nhóm kết nối. Trong iOS — factory dịch vụ cho các môi trường khác nhau (Development/Staging/Production). Abstract Factory hiếm khi được sử dụng trực tiếp — các chức năng của nó được đảm nhận bởi các vùng chứa DI (Dagger Module, Swinject Assembly).
Swift Factory được triển khai thông qua các giao thức và phương thức tĩnh. Giao thức Factory khai báo một phương thức create() trả về một loại trừu tượng. Một factory cụ thể triển khai giao thức và tạo các đối tượng cần thiết. Swift không yêu cầu một lớp factory riêng cho các trường hợp đơn giản — một phương thức tĩnh trong enum hoặc struct là đủ. Đối với các kịch bản phức tạp, giao thức Factory với tiêm DI được sử dụng.
Factory trong iOS SDK — nhiều factory hệ thống: UIStoryboard.instantiateViewController(withIdentifier:), NSKeyedUnarchiver.unarchivedObject(ofClass:from:), JSONDecoder().decode(_:from:). Các nhà phát triển tạo factory cho ViewController (StoryboardFactory), cho dịch vụ (ServiceFactory) và cho mô hình dữ liệu. Factory Method được sử dụng tích cực trong các kiến trúc VIPER và Clean Swift để tạo các mô-đun màn hình.
Factory + DI — một giải pháp thay thế hiện đại: vùng chứa DI (Swinject, Factory) tự động tạo factory cho các loại đã đăng ký. Vùng chứa lưu trữ công thức tạo đối tượng và giải quyết các phụ thuộc. Thư viện Factory (github.com/hmlongco/Factory) sử dụng @Injected(.service) để tiêm tự động. Các factory DI được kiểm thử bằng cách thay thế toàn bộ mô-đun với một dòng duy nhất: container.register { MockService() }.
Android Factory — một ví dụ cổ điển: ViewModelProvider.Factory để tạo ViewModel với tham số. Google khuyến nghị sử dụng Hilt để tự động tạo factory ViewModel — chú thích @HiltViewModel tạo Factory tự động. Đối với các đối tượng đơn giản, companion object với phương thức create() hoặc invoke() được sử dụng. Trong Kotlin, toán tử invoke cho phép gọi factory như một hàm: Factory(param).
Factory trong Jetpack Compose — factory được sử dụng để tạo trạng thái và hiệu ứng. remember { Factory.create() } tạo một đối tượng ở lần kết xuất đầu tiên và giữ nó trong suốt vòng đời của composable. ViewModel trong Compose được tạo qua viewModel() — đây là một factory do Hilt quản lý. Trong Compose, factory ít xuất hiện rõ ràng hơn, vì DI và Compose StateManager xử lý việc tạo đối tượng.
Factory vs Hilt — Dagger/Hilt tự động tạo factory tại thời điểm biên dịch. @Module + @Providers thay thế Factory Method, @Binds thay thế Abstract Factory. Các factory thủ công vẫn phù hợp cho việc chọn triển khai động trong thời gian chạy (kiểm thử A/B, feature flag). Đối với các phụ thuộc tĩnh, Hilt tự động hóa hoàn toàn việc tạo đối tượng — nhà phát triển chỉ viết giao diện và chú thích.
Câu hỏi thường gặp
Factory Method tạo một loại đối tượng thông qua kế thừa — lớp con ghi đè phương thức factory. Abstract Factory tạo một họ đối tượng thông qua hợp thành — giao diện factory khai báo phương thức cho nhiều sản phẩm. Factory Method đơn giản hơn, Abstract Factory linh hoạt hơn cho các thành phần phụ thuộc nền tảng hoặc chủ đề.
Factory phù hợp cho việc chọn triển khai động trong thời gian chạy (kiểm thử A/B, feature flag, API khác cho các cấp khác nhau). DI (Hilt, Dagger, Koin) được ưu tiên cho các phụ thuộc tĩnh — nó tự động hóa việc tạo và tiêm. Factory và DI không loại trừ lẫn nhau: DI có thể sử dụng Factory bên trong một mô-đun.
Factory được kiểm thử bằng cách thay thế factory thông qua một giao thức. Trong kiểm thử, một TestFactory được tạo, triển khai cùng giao thức và trả về các đối tượng mock. Đối với các phương thức Factory tĩnh, kiểm thử phức tạp hơn — yêu cầu vùng chứa DI hoặc swizzling. Khuyến nghị luôn sử dụng giao thức cho Factory để duy trì khả năng kiểm thử.
ViewModelProvider.Factory là một giao diện từ Jetpack cho phép tạo ViewModel với các tham số tùy chỉnh. Không có factory, ViewModel được tạo thông qua phản xạ và chỉ có thể có hàm tạo rỗng. Factory chấp nhận các tham số (kho lưu trữ, ngữ cảnh ứng dụng) và chuyển chúng đến hàm tạo ViewModel. Hilt tự động tạo Factory cho @HiltViewModel.
Factory triển khai Nguyên tắc Mở/Đóng: hệ thống mở cho việc mở rộng (triển khai mới được thêm vào factory) nhưng đóng cho việc sửa đổi (mã khách hàng không thay đổi). Thêm loại sản phẩm mới chỉ yêu cầu chỉnh sửa factory, không phải tất cả khách hàng. Đây là lợi thế chính của Factory so với việc tạo đối tượng trực tiếp.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm