"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Fábrica Simples

Fábrica Simples

Publicado em 17/11/2024
Navegar:302

O que é Fábrica Simples?

Fábrica simples não é padrão de design. Ele simplesmente separa a criação de objetos do código do cliente. Em outras palavras, o Simple factory encapsula a instanciação de objetos movendo a lógica de instanciação para uma classe separada.

Fábrica simples é frequentemente confundida com Padrão de fábrica. Vamos estudar Simple Factory para esclarecer sua diferença. Além disso, aprender o Simple Factory nos ajuda a entender facilmente o padrão do Factory.

Que problema a fábrica simples pode resolver?

A programação para implementação concreta deve ser evitada porque torna o aplicativo muito difícil de manter. É sempre preferível programar a interface. Se você estiver instanciando uma classe concreta no código do cliente, o Simple Factory será útil, pois o Simple Factory pode dissociar a criação de objetos do cliente. Isso torna nosso aplicativo mais extensível e fácil de manter.

Problema

Estamos desenvolvendo sistema para Burger Shop. O sistema precisa criar vários hambúrgueres, como hambúrguer de carne bovina, hambúrguer de frango e assim por diante.

Nossa primeira tentativa seria assim:

// Client orders a burger
Burger orderBurger(String type) {
    Burger burger;

    if (type.equals("beef")) {
        burger = new BeefBurger();
    } else if (type.equals("chicken")) {
        burger = new ChickenBurger();
    } else if (type.equals("fish")) {
        burger = new FishBurger();
    }

    burger.prepareBun();
    burger.grillPatty();
    burger.addToppings();
    burger.wrap();

    return burger;
}

O problema é que estamos codificando para implementação e não para interface. Onde? Usamos a instrução if e instanciamos uma classe concreta baseada em um tipo de hambúrguer.
Por que esse é o problema? Nosso código do cliente está fortemente acoplado à criação de objetos, resultando em menos flexibilidade!! Digamos que não vendemos mais hambúrgueres de peixe e começamos a vender hambúrgueres vegetarianos. Precisamos visitar nosso código de cliente e modificá-lo. Ou seja, não está fechado para modificação.

Solução

Para resolver o problema, podemos criar uma classe separada que será responsável apenas pela criação do objeto. Então nosso código cliente não precisa se preocupar com a criação de objetos e pode depender de abstração. Essa técnica é conhecida como "Encapsular o que varia". Esperamos que o código sobre a instanciação de objetos concretos seja alterado com frequência, enquanto os processos prepareBun(), grillPatty(), addToppings(), wrap() provavelmente permanecerão os mesmos entre todos os hambúrgueres no futuro.
A vantagem do Simple factory é que ele pode ser reutilizado por outras classes. Poderíamos ter outras classes de clientes, como BurgerRestaurant, BurgerCateringShop, que usarão o método SimpleBurgerFactory.createBurger().

Simple Factory

  1. Cliente
    O cliente instancia um objeto hambúrguer específico por meio do SimpleBurgerFactory. Observe que da perspectiva do cliente, não sabemos qual hambúrguer concreto será criado, ou seja, a lógica de criação de objetos agora está desacoplada do cliente.

  2. SimpleBurgerFactory
    Esta classe encapsula o que varia, que neste caso é a lógica de criação de objetos! createBurger() é declarado como método estático porque o cliente deseja usar esta classe para instanciar o objeto (é claro que não podemos ter uma instância antes de instanciá-lo!). createBurger() aceita enum BurgerType para determinar qual tipo de hambúrguer deve ser criado.

  3. Hambúrguer
    Esta classe abstrata fornece uma interface comum entre todos os hambúrgueres e define comportamentos padrão.

  4. Subclasses de hambúrguer
    Aqui estão nossos produtos de concreto. Eles podem implementar comportamentos específicos substituindo métodos, desde que estendam a classe Burger.

Estrutura

Simple Factory

Código

public enum BurgerType {
    BEEF,
    CHICKEN,
    FISH,
    VEGGIE
}
// Abstract Product
public abstract class Burger {

    public BurgerType burgerType;
    public List toppings = new ArrayList();

    public void prepareBun() {
        System.out.println("Preparing a bun");
    }

    public void grillPatty() {
        if (burgerType == null) {
            throw new IllegalStateException("pattyType is undefined");
        }
        System.out.println("Grill a "   burgerType   " patty");
    }

    public void addToppings() {
        for (String item : toppings) {
            System.out.println("Add "   item);
        }
    }

    public void wrap() {
        System.out.println("Wrap a burger up");
    }
}
// Concrete product
public class BeefBurger extends Burger {

    public BeefBurger() {
        burgerType = BurgerType.BEEF;
        List items = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce");
        toppings.addAll(items);
    }
}
// Concrete product
public class VeggieBurger extends Burger {

    public VeggieBurger() {
        burgerType = BurgerType.VEGGIE;
        List items = List.of("smoked paprika", "garlic chips", "crushed walnuts", "veggie sauce");
        toppings.addAll(items);
    }

    // Concrete product can implement specific behavior that differs from other products
    @Override
    public void wrap() {
        System.out.println("Wrapping paper shouldn't print any meats but vegetables");
    }
}
// Simple factory, responsible for instantiating an object
public class SimpleBurgerFactory {

    public static Burger createBurger(BurgerType type) {
        return switch (type) {
            case BEEF -> new BeefBurger();
            case CHICKEN -> new ChickenBurger();
            case FISH -> new FishBurger();
            case VEGGIE -> new VeggieBurger();
            default -> throw new IllegalArgumentException("unknown burger type");
        };
    }
}
public class Client {

    public static void main(String[] args) {
        Burger burger = orderBurger(BurgerType.VEGGIE);
        System.out.println(burger); // Check if the object is actually veggie burger
    }

    public static Burger orderBurger(BurgerType type) {
        // Factory is responsible for object creation
        Burger burger = SimpleBurgerFactory.createBurger(type);

        burger.prepareBun();
        burger.grillPatty();
        burger.addToppings();
        burger.wrap();

        return burger;
    }
}

Saída:

Preparing a bun
Grill a VEGGIE patty
Add smoked paprika
Add garlic chips
Add crushed walnuts
Add veggie sauce
Wrapping paper shouldn't print any meats but vegetables
com.factories.simpleFactory.VeggieBurger@9807454

Armadilhas

  • O código de tomada de decisão para instanciação de objetos pode ser mais complexo em algum momento. Nesse caso, podemos também considerar o uso do método Factory.

Comparação com padrão de fábrica

  • Na fábrica simples, normalmente há uma classe de fábrica para decidir que tipo de produto criar, enquanto o padrão de fábrica pode introduzir várias fábricas.
  • A fábrica simples geralmente usa métodos estáticos para criar objetos, o que facilita a chamada, mas é difícil de estender. Por outro lado, o método Factory usa um método abstrato na superclasse, que atua como interface para todas as fábricas e subclasses fornecerá implementação concreta para instanciação de objetos.

Você pode verificar todas as implementações de padrões de design aqui.
Repositório GitHub


P.S.
Sou novo em escrever um blog de tecnologia, se você tiver conselhos para melhorar minha redação ou tiver algum ponto confuso, deixe um comentário!
Obrigado por ler :)

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/sota_333ad4b72095606ab40c/simple-factory-3bnl?1 Se houver alguma violação, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3