Today I Learned 11/05/2022
Factory
Propósito
Problema
Solução
Estrutura
Implementação
Referencias
Factory
Propósito
Fornecer uma interface para criar objetos em uma superclasse, mas permitir que as subclasses alterem o tipo de objetos que serão criados
Problema
Se você tem um código muito acoplado a uma á uma classe em especifico, caso um dia precise adicionar uma outra classe vai ter problemas, por exemplo, uma empresa de logistica que usa somente caminhões, e o sistema está fortemente acoplado a classe de caminhão, caso algum dia queira ser implementada a classe navio
isso vai gerar uma refatoração gigantesca no código
Solução
O padrão factory sugere substituir as chamadas diretas de construção de objetos, nesse caso caminhão para um método factory e ai esse factory vai ficar responsavel por criar e retornar os objetos que nesse caso chamamos de produtos
Nesse exemplo do site refactoring guru, podemos ver que temos uma classe Logistics
que contem um método createTransport
que é uma factory, as classes RoadLogistics
e SeaLogistics
implementam essa classe Logistics e modificam o createTransport
para retornar um caminhão e um návio respectivamente
Porem existe uma limitação, as subclasses só podem retornar tipos diferentes de produtos caso eles implemente uma mesma interface em comum. Isso ajuda para que quando o cliente faça uma chamada ele apenas precisa saber qual a interface desses produtos e pode tratar todos da mesma forma pois ele sabe que todos vão ter os mesmos métodos
Estrutura
O Produto declara a interface que que os objetos vão implementar
O produto concreto A e B são diferentes implementações da interface Produto
A classe Creator tem um método factory que cria um produto do tipo Produto
(Apesar do nome a principal responsabilidade da classe creator não é criar produtos)Criadores concretos sobescrevem a classe Creator para retornar diferente produtos no seus metodos factory
Implementação
abstract class Creator {
public abstract factoryMethod(): Product;
public someOperation(): string {
const product = this.factoryMethod();
console.log(product.opertation());
}
}
class ConcreteCreator1 extends Creator {
public factoryMethod(): Product {
return new ConcreteProduct1();
}
}
class ConcreteCreator2 extends Creator {
public factoryMethod(): Product {
return new ConcreteProduct2();
}
}
os concrete creators vão extender o Creator e mudar apenas o método factory
interface Product {
operation(): string;
}
class ConcreteProduct1 implements Product {
public operation(): string {
return '{Result of the ConcreteProduct1}';
}
}
class ConcreteProduct2 implements Product {
public operation(): string {
return '{Result of the ConcreteProduct2}';
}
}
function clientCode(creator: Creator) {
console.log(creator.someOperation());
}
a partir dai o clientCode
precisa apenas receber qualquer classe que extende o creator e ele tem certeza que essa classe vai ter o método someOperation
que pode fazer coisas diferentes como por exemplo o no exemplo do barco e caminhão ambos podem ter o método delivery que funcionam de formas diferentes mas isso não import para o clientCode
Top comments (0)