Factory — een creatiepatroon dat het maken van objecten delegeert aan fabrieksmethoden. In mobiele ontwikkeling worden Factory Method en Abstract Factory gebruikt om ViewModel, NetworkClient, Repository en andere afhankelijkheden te creëren. Factory isoleert de instantiatielogica, waardoor implementaties eenvoudiger kunnen worden vervangen. Meer — op Refactoring Guru: Factory Method.
Belangrijkste punten
Factory — een creatiepatroon uit de GoF-catalogus. Het hoofdidee: de logica voor het maken van objecten uit de clientcode halen en in een aparte methode of klasse plaatsen. De client werkt met een interface of abstracte klasse, en de concrete implementatie wordt door de fabriek gemaakt. Dit implementeert het principe van inversie van afhankelijkheden (Dependency Inversion): de client is niet afhankelijk van concrete klassen, alleen van abstracties.
Twee varianten Factory: Factory Method en Abstract Factory. Factory Method — één methode in een klasse die subklassen overschrijven om objecten te maken. Abstract Factory — een interface met een familie van fabrieksmethoden voor het maken van groepen onderling verbonden objecten. Beide varianten lossen hetzelfde probleem op: de client roept niet direct new MyClass() aan, maar vraagt de fabriek om een object te maken op basis van het type of parameters.
Factory vs new() — directe objectcreatie koppelt code star aan een concrete implementatie. Factory voegt een tussenlaag toe: het wijzigen van de implementatie vereist alleen aanpassingen in de fabriek, niet in alle clients. In mobiele ontwikkeling wordt Factory actief gebruikt voor het maken van ViewModel (ViewModelProvider.Factory), netwerkclients (Retrofit.create()), lijstadapaters en serialisatiefabrieken. DI-containers (Dagger, Koin) genereren automatisch fabrieken.
Factory Method — een methode gedeclareerd in een protocol of abstracte klasse die een object van een specifiek type retourneert. Subklassen implementeren deze methode en maken concrete instanties. In Swift kan dit een static method in een protocol zijn of een methode in een basisklasse. In Kotlin — companion object met een fabrieksmethode of open fun in een abstracte klasse. Het patroon wordt veel gebruikt voor het maken van parsers, foutfabrieken en query-builders.
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()
}
}
}
// Gebruik
let gateway = PaymentFactory.create(type: .stripe)
Kotlin-versie Factory Method gebruikt companion object of sealed class om typen te beperken. Sealed class garandeert dat de when-tak alle mogelijke typen dekt — de compiler controleert de volledigheid. Dit is typisch voor Android-projecten, waar de fabriek verschillende Repository- of DataSource-implementaties maakt afhankelijk van build flavour of configuratie.
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 — een patroon voor het maken van families van onderling verbonden of afhankelijke objecten zonder hun concrete klassen te specificeren. De client werkt met de interface van de abstracte fabriek, die methoden definieert voor het maken van elk product uit de familie. De concrete fabriek implementeert de interface en maakt objecten van een specifieke variant. Een fabriek van UI-componenten voor iOS maakt bijvoorbeeld UIButton, UILabel, UITableView, en voor Android — Button, TextView, RecyclerView.
Abstract Factory vs Factory Method — Factory Method maakt één type object via overerving, Abstract Factory maakt een familie van objecten via compositie. Factory Method wordt overschreven in subklassen, Abstract Factory biedt meerdere fabrieksmethoden via een protocol. Abstract Factory bevat vaak meerdere Factory Method-instanties. In mobiele ontwikkeling wordt Abstract Factory gebruikt voor platformspecifieke componenten, thema's en databasefabrieken.
| Kenmerk | Factory Method | Abstract Factory |
|---|---|---|
| Aantal producten | Eén | Familie (meerdere) |
| Mechanisme | Overerving (override) | Compositie (protocol/interface) |
| Voorbeeld iOS | PaymentFactory.create() | UIComponentFactory voor iOS/Android |
| Voorbeeld Android | ViewModelProvider.Factory | ThemeFactory: knoppen, teksten, kaarten maken |
| Flexibiliteit | Eenvoudige subklasse vervanging | Volledige familiewissel |
Echt voorbeeld Abstract Factory in Android — implementatie van verschillende databasetypen (SQLite vs Room) via een uniforme DatabaseFactory-interface. De fabriek maakt DAO-objecten, migraties en verbindingspools. In iOS — een servicefabriek voor verschillende omgevingen (Development/Staging/Production). Abstract Factory wordt zelden direct gebruikt — de functies worden overgenomen door DI-containers (Dagger Module, Swinject Assembly).
Swift Factory wordt geïmplementeerd via protocollen en statische methoden. Het Factory-protocol declareert de methode create() die een abstract type retourneert. De concrete fabriek implementeert het protocol en maakt de benodigde objecten. Swift vereist geen aparte fabrieksklasse voor eenvoudige gevallen — een statische methode in een enum of struct is voldoende. Voor complexe scenario's wordt het Factory-protocol gebruikt met injectie via DI.
Factory in iOS SDK — veel systeemfabrieken: UIStoryboard.instantiateViewController(withIdentifier:), NSKeyedUnarchiver.unarchivedObject(ofClass:from:), JSONDecoder().decode(_:from:). Ontwikkelaars maken fabrieken voor ViewController (StoryboardFactory), voor services (ServiceFactory) en voor gegevensmodellen. Factory Method wordt actief gebruikt in VIPER- en Clean Swift-architecturen voor het maken van schermmodules.
Factory + DI — modern alternatief: DI-container (Swinject, Factory) genereert automatisch fabrieken voor geregistreerde typen. De container bewaart recepten voor objectcreatie en lost afhankelijkheden op. De Factory-bibliotheek (github.com/hmlongco/Factory) gebruikt @Injected(.service) voor automatische injectie. DI-fabrieken worden getest door de hele module met één regel te vervangen: container.register { MockService() }.
Android Factory — klassiek voorbeeld: ViewModelProvider.Factory voor het maken van ViewModel met parameters. Google raadt het gebruik van Hilt aan voor het automatisch genereren van ViewModel-fabrieken — de @HiltViewModel-annotatie maakt automatisch een Factory aan. Voor eenvoudige objecten wordt companion object gebruikt met de methode create() of invoke(). In Kotlin kunt u met de operator invoke de fabriek als functie aanroepen: Factory(param).
Factory in Jetpack Compose — fabrieken worden gebruikt voor het maken van toestanden en effecten. remember { Factory.create() } maakt een object bij de eerste weergave en behoudt het gedurende de levensduur van de composable. ViewModel in Compose wordt gemaakt via viewModel() — dit is een fabriek die door Hilt wordt beheerd. In Compose komen fabrieken minder expliciet voor, omdat DI en Compose StateManager het maken van objecten overnemen.
Factory vs Hilt — Dagger/Hilt genereert automatisch fabrieken tijdens de compilatiefase. @Module + @Provides vervangt Factory Method, @Binds vervangt Abstract Factory. Handmatige fabrieken blijven relevant voor dynamische implementatiekeuze tijdens runtime (A/B-testen, feature flags). Voor statische afhankelijkheden automatiseert Hilt het maken van objecten volledig — de ontwikkelaar schrijft alleen de interface en annotaties.
Veelgestelde vragen
Factory Method maakt één type object via overerving — de subklasse overschrijft de fabrieksmethode. Abstract Factory maakt een familie van objecten via compositie — de fabrieksinterface declareert methoden voor meerdere producten. Factory Method is eenvoudiger, Abstract Factory is flexibeler voor platformspecifieke of thematische componenten.
Factory is gerechtvaardigd voor dynamische implementatiekeuze tijdens runtime (A/B-tests, feature flags, verschillende API voor verschillende tarieven). DI (Hilt, Dagger, Koin) heeft de voorkeur voor statische afhankelijkheden — het automatiseert creatie en injectie. Factory en DI sluiten elkaar niet uit: DI kan Factory binnen een module gebruiken.
Factory wordt getest door de fabriek via een protocol te vervangen. In de test wordt een TestFactory gemaakt die hetzelfde protocol implementeert en mock-objecten retourneert. Voor statische Factory-methoden is testen moeilijker — er is een DI-container of swizzling nodig. Het wordt aanbevolen altijd een protocol voor Factory te gebruiken om de testbaarheid te behouden.
ViewModelProvider.Factory — een interface uit Jetpack waarmee u ViewModel met aangepaste parameters kunt maken. Zonder fabriek wordt ViewModel gemaakt via reflectie en kan het alleen een lege constructor hebben. Factory ontvangt parameters (repository, application context) en geeft deze door aan de constructor van ViewModel. Hilt genereert automatisch een Factory voor @HiltViewModel.
Factory implementeert het Open-Closed-principe: het systeem is open voor uitbreiding (een nieuwe implementatie wordt aan de fabriek toegevoegd), maar gesloten voor wijziging (de clientcode verandert niet). Het toevoegen van een nieuw producttype vereist alleen wijzigingen in de fabriek, niet in alle clients. Dit is het belangrijkste voordeel van Factory ten opzichte van directe objectcreatie.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook