Site de Referência: https://refactoring.guru/pt-br/design-patterns/abstract-factory
Livro de Referência: Padrões de Projeto
Considerando que o Abstract Factory é um padrão de projeto que resolve o problema de criar famílias inteiras de produtos sem especificar suas classes concretas, consideremos a seguinte implementação:
Suponhamos que precisemos criar uma aplicação que inicie o processo de fabricação de um carro e em seguita grave a marca do carro fabricado. Considerando que existem várias marcas de carro, vamos então aplicar o padrão Abstract Factory:
DIAGRAMA DA IMPLEMENTAÇÃO
A interface CarFactory, que é uma fábrica abstrata, declara o conjunto de funções que retorna diferentes produtos abstratos como uma família que está relacionada a um tema ou a um conceito de alto nível. Nesse caso, como produtos abstratos temos Car e Brand
interface CarFactory{
fun createCar(): Car
fun setBrandCar(): Brand
}
Separamos as variantes em fábricas concretas, que serão responsáveis por produzir uma família de produtos da mesma variante, garantindo que os produtos resultantes sejam compatíveis. Cada Assinatura de função retorna um produto abstrato, enquanto que dentro da função, um produto concreto é instanciado:
Cada Fábrica concreta tem uma variante do produto conrespondente:
class FiatFactory: CarFactory {
override fun createCar(): Car {
return FiatCar()
}
override fun setBrandCar(): Brand {
return FiatBrand()
}
}
class FordFactory: CarFactory {
override fun createCar(): Car {
return FordCar()
}
override fun setBrandCar(): Brand {
return FordBrand()
}
}
Cada produto de uma respectiva família de produtos, deverá ter uma interface base e todas as variantes dos produtos implementarão essa iterface:
interface Car{
fun makeCar()
}
Dessa forma, todo produto concreto é criado por uma fábrica concreta:
class FiatCar: Car {
override fun makeCar() {
println("Fabricando um Fiat...")
}
}
class FordCar: Car {
override fun makeCar() {
println("Fabricando um Ford...")
}
}
Essa é a interface base de outro produto e que só podem interagir entre produtos da mesma variante:
interface Brand{
fun writeBranding()
}
class FiatBrand: Brand {
override fun writeBranding() {
println("FIAT")
}
}
class FordBrand: Brand {
override fun writeBranding() {
println("FORD")
}
}
Prontinho, agora eu criei uma função para realizar a execução da fábrica com base na sua respectiva variante executando o processo de criação do carro e gravura da marca de acordo com com o parâmetro informado na função runApplication:
fun runApplication(brandCar: String) {
when (brandCar) {
"Fiat" -> {
FiatFactory().createCar().makeCar()
FiatFactory().setBrandCar().writeBranding()
}
"Ford" -> {
FordFactory().createCar().makeCar()
FordFactory().setBrandCar().writeBranding()
}
else -> println("Not found car!")
}
}