DEV Community

Yan.ts
Yan.ts

Posted on

Padrões criacionais Factory

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

Image description

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

Image description

  1. O Produto declara a interface que que os objetos vão implementar

  2. O produto concreto A e B são diferentes implementações da interface Produto

  3. 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)

  4. 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());
    }
}
Enter fullscreen mode Exit fullscreen mode
class ConcreteCreator1 extends Creator {
    public factoryMethod(): Product {
        return new ConcreteProduct1();
    }
}

class ConcreteCreator2 extends Creator {
    public factoryMethod(): Product {
        return new ConcreteProduct2();
    }
}
Enter fullscreen mode Exit fullscreen mode

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}';
    }
}
Enter fullscreen mode Exit fullscreen mode
function clientCode(creator: Creator) {
    console.log(creator.someOperation());
}
Enter fullscreen mode Exit fullscreen mode

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

Referencias

Top comments (0)