Factory — un modèle de création qui délègue la création d'objets à des méthodes d'usine. Dans le développement mobile, Factory Method et Abstract Factory sont utilisés pour créer ViewModel, NetworkClient, Repository et d'autres dépendances. Factory isole la logique d'instanciation, simplifiant le remplacement d'implémentations. Plus de détails — sur Refactoring Guru : Factory Method.
Points clés
Factory — un modèle de conception de création du catalogue GoF. L'idée principale : déplacer la logique de création d'objets du code client vers une méthode ou une classe séparée. Le client travaille avec une interface ou une classe abstraite, tandis que l'implémentation concrète est créée par l'usine. Cela implémente le principe d'inversion des dépendances : le client ne dépend pas de classes concrètes, seulement d'abstractions.
Deux variétés de Factory : Factory Method et Abstract Factory. Factory Method — une méthode unique dans une classe que les sous-classes redéfinissent pour créer des objets. Abstract Factory — une interface avec une famille de méthodes d'usine pour créer des groupes d'objets liés. Les deux variantes résolvent le même problème : le client n'appelle pas new MyClass() directement, mais demande à l'usine de créer un objet selon son type ou ses paramètres.
Factory vs new() — la création directe d'objets couple fortement le code à une implémentation concrète. Factory ajoute une couche : changer l'implémentation nécessite de modifier uniquement l'usine, pas tous les clients. Dans le développement mobile, Factory est activement utilisé pour créer ViewModel (ViewModelProvider.Factory), des clients réseau (Retrofit.create()), des adaptateurs de liste et des usines de sérialisation. Les conteneurs DI (Dagger, Koin) génèrent automatiquement des usines.
Factory Method — une méthode déclarée dans un protocole ou une classe abstraite qui retourne un objet d'un type spécifique. Les sous-classes implémentent la méthode, créant des instances concrètes. En Swift, cela peut être une méthode statique dans un protocole ou une méthode dans une classe de base. En Kotlin — un companion object avec une méthode d'usine ou open fun dans une classe abstraite. Le modèle est largement utilisé pour créer des analyseurs, des usines d'erreurs et des constructeurs de requêtes.
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()
}
}
}
// Utilisation
let gateway = PaymentFactory.create(type: .stripe)
Version Kotlin de Factory Method utilise companion object ou sealed class pour limiter les types. Sealed class garantit que la branche when couvre tous les types possibles — le compilateur vérifie l'exhaustivité. C'est typique pour les projets Android où l'usine crée différentes implémentations de Repository ou DataSource selon le build flavour ou la configuration.
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 modèle pour créer des familles d'objets liés ou interdépendants sans spécifier leurs classes concrètes. Le client travaille avec l'interface de l'usine abstraite, qui définit des méthodes pour créer chaque produit de la famille. Une usine concrète implémente l'interface et crée des objets d'une variante spécifique. Par exemple, une usine de composants UI pour iOS crée UIButton, UILabel, UITableView, tandis que pour Android — Button, TextView, RecyclerView.
Abstract Factory vs Factory Method — Factory Method crée un type d'objet par héritage, Abstract Factory crée une famille d'objets par composition. Factory Method est redéfini dans les sous-classes, Abstract Factory fournit plusieurs méthodes d'usine via un protocole. Abstract Factory contient souvent plusieurs Factory Method. Dans le développement mobile, Abstract Factory est utilisé pour les composants dépendants de la plateforme, les thèmes de conception et les usines de bases de données.
| Caractéristique | Factory Method | Abstract Factory |
|---|---|---|
| Nombre de produits | Un | Famille (plusieurs) |
| Mécanisme | Héritage (override) | Composition (protocole/interface) |
| Exemple iOS | PaymentFactory.create() | UIComponentFactory pour iOS/Android |
| Exemple Android | ViewModelProvider.Factory | ThemeFactory : création de boutons, textes, cartes |
| Flexibilité | Remplacement simple de sous-classe | Remplacement complet de famille |
Cas réel d'Abstract Factory sous Android — implémentation de différents types de bases de données (SQLite vs Room) via une seule interface DatabaseFactory. L'usine crée des objets DAO, des migrations et des pools de connexions. Sous iOS — une usine de services pour différents environnements (Development/Staging/Production). Abstract Factory est rarement utilisé directement — ses fonctions sont reprises par les conteneurs DI (Dagger Module, Swinject Assembly).
Swift Factory est implémenté via des protocoles et des méthodes statiques. Le protocole Factory déclare une méthode create() retournant un type abstrait. Une usine concrète implémente le protocole et crée les objets nécessaires. Swift ne nécessite pas de classe d'usine séparée pour les cas simples — une méthode statique dans un enum ou une struct suffit. Pour les scénarios complexes, un protocole Factory avec injection DI est utilisé.
Factory dans iOS SDK — de nombreuses usines système : UIStoryboard.instantiateViewController(withIdentifier:), NSKeyedUnarchiver.unarchivedObject(ofClass:from:), JSONDecoder().decode(_:from:). Les développeurs créent des usines pour ViewController (StoryboardFactory), pour les services (ServiceFactory) et pour les modèles de données. Factory Method est activement utilisé dans les architectures VIPER et Clean Swift pour créer des modules d'écran.
Factory + DI — une alternative moderne : un conteneur DI (Swinject, Factory) génère automatiquement des usines pour les types enregistrés. Le conteneur stocke des recettes de création d'objets et résout les dépendances. La bibliothèque Factory (github.com/hmlongco/Factory) utilise @Injected(.service) pour l'injection automatique. Les usines DI sont testées en remplaçant un module entier par une seule ligne : container.register { MockService() }.
Android Factory — un exemple classique : ViewModelProvider.Factory pour créer ViewModel avec paramètres. Google recommande d'utiliser Hilt pour la génération automatique d'usines ViewModel — l'annotation @HiltViewModel crée Factory automatiquement. Pour les objets simples, un companion object avec méthode create() ou invoke() est utilisé. En Kotlin, l'opérateur invoke permet d'appeler l'usine comme une fonction : Factory(param).
Factory dans Jetpack Compose — les usines sont utilisées pour créer des états et des effets. remember { Factory.create() } crée un objet au premier rendu et le conserve pendant la durée de vie du composable. ViewModel dans Compose est créé via viewModel() — c'est une usine gérée par Hilt. Dans Compose, les usines sont moins courantes explicitement, car DI et Compose StateManager gèrent la création d'objets.
Factory vs Hilt — Dagger/Hilt génère automatiquement des usines à la compilation. @Module + @Services remplace Factory Method, @Binds remplace Abstract Factory. Les usines manuelles restent pertinentes pour la sélection dynamique d'implémentation à l'exécution (tests A/B, feature flags). Pour les dépendances statiques, Hilt automatise entièrement la création d'objets — le développeur écrit uniquement des interfaces et des annotations.
Foire aux questions
Factory Method crée un type d'objet par héritage — la sous-classe redéfinit la méthode d'usine. Abstract Factory crée une famille d'objets par composition — l'interface d'usine déclare des méthodes pour plusieurs produits. Factory Method est plus simple, Abstract Factory est plus flexible pour les composants dépendants de la plateforme ou thématiques.
Factory est justifiée pour la sélection dynamique d'implémentation à l'exécution (tests A/B, feature flags, API différente pour différents niveaux). DI (Hilt, Dagger, Koin) est préférable pour les dépendances statiques — il automatise la création et l'injection. Factory et DI ne sont pas mutuellement exclusifs : DI peut utiliser Factory à l'intérieur d'un module.
Factory est testée en remplaçant l'usine via un protocole. Dans le test, une TestFactory est créée, implémentant le même protocole et retournant des objets mock. Pour les méthodes statiques de Factory, le test est plus complexe — il nécessite un conteneur DI ou du swizzling. Il est recommandé de toujours utiliser un protocole pour Factory afin de maintenir la testabilité.
ViewModelProvider.Factory est une interface de Jetpack qui permet de créer ViewModel avec des paramètres personnalisés. Sans usine, ViewModel est créé par réflexion et ne peut avoir qu'un constructeur vide. Factory accepte des paramètres (référentiel, contexte d'application) et les transmet au constructeur de ViewModel. Hilt génère Factory automatiquement pour @HiltViewModel.
Factory implémente le principe Ouvert/Fermé : le système est ouvert à l'extension (une nouvelle implémentation est ajoutée à l'usine) mais fermé à la modification (le code client ne change pas). Ajouter un nouveau type de produit nécessite de modifier uniquement l'usine, pas tous les clients. C'est l'avantage clé de Factory par rapport à la création directe d'objets.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi