Fábricas e o princípio da responsabilidade exclusiva

SingleResponsibilityPrinciple

Seguindo o nosso curso de programação hoje não veremos um padrão de projeto que vai se concentrar em melhorar o código que misturas criação de um objeto interações no objeto e como este, protegendo -nos nos princípios sólidos , ou seja, o princípio da responsabilidade única , ver isso, já que não está correto e que teremos que realizar uma refatoração do código. Essa refatoração levará à fábrica. Temos que deixar claro que, para nós, uma fábrica é qualquer método ou objeto usado para criar outros objetos . No entanto, o termo fábricas refere-se aos padrões de criação Abstract Factory e Factory Method que veremos mais adiante.

Exemplo

Suponha que estamos desenvolvendo um aplicativo para uma pizzaria onde teremos que criar nossa Pizza, mas também prepará-los, cozinhá-los, cortá-los … A primeira coisa que vem à mente, seguindo um modelo de desenvolvimento orientado a objetos, é criar uma classe Pizza com um método responsável pela criação da Pizza, mas também pela preparação.

public Class Pizzeria {
    Pizza orderPizza() {  
       Pizza pizza;
       pizza = new Pizza();

       pizza.prepare();
       pizza.bake();
       pizza.cut();
       pizza.box();
       return pizza;

    }
}

A primeira coisa que podemos pensar nesse design é que talvez na pizzaria você queira distinguir os diferentes tipos de pizza, como os quatro queijos, lingüiça, vegetais … Podemos substituir o método por algo semelhante a:

Pizza orderPizza(String type) {
    Pizza pizza;

    if (type.equals("cheese")) {
        pizza = new CheesePizza();
    } else if (type.equals("greek")) {
        pizza = new GreekPizza();
    else if (type.equals("pepperoni")) {
        pizza = new PepperoniPizza();
    }

    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    return pizza;
}

Quando você pede uma pizza, passamos o tipo de pizza a ser criada. O que acontece se adicionarmos novos tipos de pizza ou eliminarmos alguns? Nesse caso, parece razoável pensar que a primeira parte do método (onde criamos a Pizza) é mais provável de mudar ao longo do tempo (porque a seleção de pizzas é alterada), mas também tem uma parte que se espera que não seja alterada. Temos que ter em mente que, neste design, cada tipo de pizza sabe como se preparar . Em muitos casos, em problemas reais, isso não precisa necessariamente ser assim.

Relacionado:  Você pode imaginar o Macintosh II em um smartwatch? Bem, agora é possível

Temos um problema, temos que aplicar os princípios do SOLID nos quais eles indicam que devemos separar a criação de um objeto com o que seria a interação com ele . Tomaremos a lógica de criar o objeto fora do método orderPizza para um objeto separado que chamaremos de SimplePizzaFactory. Sempre devemos deixar claro que uma classe deve ser responsável por criar e gerenciar objetos ou usá-los (interagir), mas nunca os dois . Deve ter pouco acoplamento; divisão de tarefas Você deve cumprir o princípio de responsabilidade exclusiva.

uml_inicial_factoryMethod

Teríamos um código semelhante a:

public class Pizzeria {
    SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory) {
      this.factory = factory;
    }
    public Pizza orderPizza(String type) {
      Pizza pizza;
      pizza = factory.createPizza(type);
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
      return pizza;
    }
}

Enquanto a classe responsável pela criação das pizzas seria:

public class SimplePizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals("queso")) {
            pizza = new PizzaQueso();
        } else if (type.equals("chorizo")) {
            pizza = new PizzaChorizo();
        } else if (type.equals("vegetal")) {
            pizza = new PizzaVegetal();
        }
        return pizza;
    }
}

Afinal, o código ainda é parametrizado pelo tipo de pizza, e tudo o que fizemos foi transferir o problema para outro objeto . De fato, é assim e, nesse exemplo bobo, nenhuma vantagem é apreciada (além da legibilidade do código e de que cada método e, se possível, cada classe, se dedicam a uma coisa, que por si só só possivelmente já o fez). valeu a pena separá-lo). Mas temos que pensar que muitas vezes essa lógica se repete em diferentes pontos do programa. A chave é eliminar a criação dos objetos concretos da lógica do cliente, para que você só precise ir a um site quando as classes específicas mudarem.

Em artigos futuros, veremos como evoluir este exemplo em direção a algum padrão de design de criação. Convido você a ter, se for capaz de executar uma refatoração desse código para uma Fábrica Abstrata ou um Método de Fábrica.

 

Você pode estar interessado:

Deixe um comentário