Factory — un model de creare care delegă crearea obiectelor metodelor fabrică. În dezvoltarea mobilă, Factory Method și Abstract Factory sunt utilizate pentru a crea ViewModel, NetworkClient, Repository și alte dependențe. Factory izolează logica de instanțiere, simplificând înlocuirea implementărilor. Mai multe — pe Refactoring Guru: Factory Method.
Principalele
Factory — un model de proiectare de creare din catalogul GoF. Ideea principală: mutarea logicii de creare a obiectelor din codul client într-o metodă sau clasă separată. Clientul lucrează cu o interfață sau o clasă abstractă, iar implementarea concretă este creată de fabrică. Aceasta implementează principiul inversării dependențelor (Dependency Inversion): clientul nu depinde de clase concrete, ci doar de abstracții.
Două varietăți Factory: Factory Method și Abstract Factory. Factory Method — o singură metodă în clasă, pe care subclasele o suprascriu pentru a crea obiecte. Abstract Factory — o interfață cu o familie de metode fabrică pentru crearea de grupuri de obiecte interdependente. Ambele variante rezolvă aceeași problemă: clientul nu apelează direct new MyClass(), ci cere fabricii să creeze un obiect după tipul sau parametrii săi.
Factory vs new() — crearea directă a obiectelor leagă rigid codul de o implementare concretă. Factory adaugă un strat intermediar: schimbarea implementării necesită modificări doar în fabrică, nu în toți clienții. În dezvoltarea mobilă, Factory este utilizată activ pentru crearea ViewModel (ViewModelProvider.Factory), a clienților de rețea (Retrofit.create()), a adaptoarelor de liste și a fabricilor de serializare. Containerele DI (Dagger, Koin) generează automat fabrici.
Factory Method — o metodă declarată într-un protocol sau o clasă abstractă, care returnează un obiect de un tip specific. Subclasele implementează această metodă, creând instanțe concrete. În Swift, aceasta poate fi o static method într-un protocol sau o metodă într-o clasă de bază. În Kotlin — companion object cu o metodă fabrică sau open fun într-o clasă abstractă. Modelul este utilizat pe scară largă pentru crearea de analizoare, fabrici de erori și constructori de cereri.
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()
}
}
}
// Utilizare
let gateway = PaymentFactory.create(type: .stripe)
Versiunea Kotlin Factory Method utilizează companion object sau sealed class pentru a restrânge tipurile. Sealed class garantează că ramura when acoperă toate tipurile posibile — compilatorul verifică completitudinea. Acest lucru este tipic pentru proiectele Android, unde fabrica creează diferite implementări Repository sau DataSource în funcție de build flavour sau configurație.
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 — un model pentru crearea de familii de obiecte interdependente sau interdependente fără a specifica clasele lor concrete. Clientul lucrează cu interfața fabricii abstracte, care definește metode pentru crearea fiecărui produs al familiei. Fabrica concretă implementează interfața și creează obiecte ale unui anumit variant. De exemplu, o fabrică de componente UI pentru iOS creează UIButton, UILabel, UITableView, iar pentru Android — Button, TextView, RecyclerView.
Abstract Factory vs Factory Method — Factory Method creează un singur tip de obiect prin moștenire, Abstract Factory creează o familie de obiecte prin compoziție. Factory Method este suprascris în subclase, Abstract Factory oferă mai multe metode fabrică printr-un protocol. Abstract Factory conține adesea mai multe Factory Method. În dezvoltarea mobilă, Abstract Factory este utilizată pentru componente dependente de platformă, teme și fabrici de baze de date.
| Caracteristică | Factory Method | Abstract Factory |
|---|---|---|
| Număr de produse | Unul | Familie (mai multe) |
| Mecanism | Moștenire (override) | Compoziție (protocol/interface) |
| Exemplu iOS | PaymentFactory.create() | UIComponentFactory pentru iOS/Android |
| Exemplu Android | ViewModelProvider.Factory | ThemeFactory: crearea butoanelor, textelor, cardurilor |
| Flexibilitate | Înlocuire simplă a subclasei | Înlocuire completă a familiei |
Caz real Abstract Factory în Android — implementarea diferitelor tipuri de baze de date (SQLite vs Room) printr-o interfață unică DatabaseFactory. Fabrica creează obiecte DAO, migrări și pool-uri de conexiuni. În iOS — o fabrică de servicii pentru diferite medii (Development/Staging/Production). Abstract Factory este rar utilizată direct — funcțiile sale sunt preluate de containerele DI (Dagger Module, Swinject Assembly).
Swift Factory este implementată prin protocoale și metode statice. Protocolul Factory declară metoda create() care returnează un tip abstract. Fabrica concretă implementează protocolul și creează obiectele necesare. Swift nu necesită o clasă-fabrică separată pentru cazuri simple — este suficientă o metodă statică într-un enum sau struct. Pentru scenarii complexe, se utilizează protocolul Factory cu injectare prin DI.
Factory în iOS SDK — multe fabrici de sistem: UIStoryboard.instantiateViewController(withIdentifier:), NSKeyedUnarchiver.unarchivedObject(ofClass:from:), JSONDecoder().decode(_:from:). Dezvoltatorii creează fabrici pentru ViewController (StoryboardFactory), pentru servicii (ServiceFactory) și pentru modele de date. Factory Method este utilizat activ în arhitecturile VIPER și Clean Swift pentru crearea modulelor de ecrane.
Factory + DI — alternativa modernă: containerul DI (Swinject, Factory) generează automat fabrici pentru tipurile înregistrate. Containerul stochează rețetele de creare a obiectelor și rezolvă dependențele. Biblioteca Factory (github.com/hmlongco/Factory) utilizează @Injected(.service) pentru injectarea automată. Fabricile DI se testează prin înlocuirea întregului modul cu o singură linie: container.register { MockService() }.
Android Factory — exemplul clasic: ViewModelProvider.Factory pentru crearea ViewModel cu parametri. Google recomandă utilizarea Hilt pentru generarea automată a fabricilor ViewModel — adnotarea @HiltViewModel creează Factory automat. Pentru obiecte simple, se utilizează companion object cu metoda create() sau invoke(). În Kotlin, operatorul invoke permite apelarea fabricii ca pe o funcție: Factory(param).
Factory în Jetpack Compose — fabricile sunt utilizate pentru crearea stărilor și efectelor. remember { Factory.create() } creează un obiect la prima randare și îl păstrează pe durata de viață a composable-ului. ViewModel în Compose este creat prin viewModel() — aceasta este o fabrică gestionată de Hilt. În Compose, fabricile apar mai rar explicit, deoarece DI și Compose StateManager preiau crearea obiectelor.
Factory vs Hilt — Dagger/Hilt generează automat fabrici în faza de compilare. @Module + @Providers înlocuiește Factory Method, @Binds înlocuiește Abstract Factory. Fabricile manuale rămân relevante pentru alegerea dinamică a implementării în runtime (testare A/B, feature flags). Pentru dependențe statice, Hilt automatizează complet crearea obiectelor — dezvoltatorul scrie doar interfața și adnotările.
Întrebări frecvente
Factory Method creează un singur tip de obiect prin moștenire — subclasa suprascrie metoda fabrică. Abstract Factory creează o familie de obiecte prin compoziție — interfața fabricii declară metode pentru mai multe produse. Factory Method este mai simplu, Abstract Factory este mai flexibil pentru componente dependente de platformă sau tematice.
Factory este justificată pentru alegerea dinamică a implementării în runtime (teste A/B, feature flags, API diferit pentru tarife diferite). DI (Hilt, Dagger, Koin) este preferabil pentru dependențe statice — automatizează crearea și injectarea. Factory și DI nu se exclud reciproc: DI poate utiliza Factory în interiorul unui modul.
Factory se testează prin înlocuirea fabricii printr-un protocol. În test se creează o TestFactory care implementează același protocol și returnează obiecte mock. Pentru metodele statice Factory, testarea este mai dificilă — necesită un container DI sau swizzling. Se recomandă să se utilizeze întotdeauna un protocol pentru Factory pentru a păstra testabilitatea.
ViewModelProvider.Factory — o interfață din Jetpack care permite crearea ViewModel cu parametri personalizați. Fără fabrică, ViewModel este creat prin reflexie și poate avea doar un constructor gol. Factory primește parametri (repository, application context) și îi transmite constructorului ViewModel. Hilt generează Factory automat pentru @HiltViewModel.
Factory implementează principiul Open-Closed: sistemul este deschis pentru extindere (o nouă implementare se adaugă în fabrică), dar închis pentru modificare (codul client nu se schimbă). Adăugarea unui nou tip de produs necesită modificări doar în fabrică, nu în toți clienții. Acesta este avantajul cheie al Factory față de crearea directă a obiectelor.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și