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.
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.
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.
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().
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.
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.
Hambúrguer
Esta classe abstrata fornece uma interface comum entre todos os hambúrgueres e define comportamentos padrão.
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.
public enum BurgerType { BEEF, CHICKEN, FISH, VEGGIE }
// Abstract Product public abstract class Burger { public BurgerType burgerType; public Listtoppings = 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; Listitems = List.of("lettuce", "pickle slices", "tomato slice", "BBQ sauce"); toppings.addAll(items); } }
// Concrete product public class VeggieBurger extends Burger { public VeggieBurger() { burgerType = BurgerType.VEGGIE; Listitems = 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
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 :)
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