Padrão de fábrica abstrata em Java

Padrão de fábrica abstrata em Java

1. Visão geral

Neste artigo, discutiremos o padrão de projeto Abstract Factory.

O livroDesign Patterns: Elements of Reusable Object-Oriented Software afirma que um Abstract Factory“provides an interface for creating families of related or dependent objects without specifying their concrete classes”. Em outras palavras, este modelo nos permite criar objetos que seguem um padrão geral.

Um exemplo do padrão de projeto Abstract Factory no JDK é onewInstance() da classejavax.xml.parsers.DocumentBuilderFactory.

2. Exemplo de padrão de projeto de fábrica abstrata

Neste exemplo, criaremos duas implementações do padrão Factory Method Design:AnimalFactoryeColorFactory.

Depois disso, gerenciaremos o acesso a eles usando um Abstract FactoryAbstractFactory:

image

Primeiro, vamos criar uma família de classeAnimal e, posteriormente, usá-la em nosso Abstract Factory.

Aqui está a interfaceAnimal:

public interface Animal {
    String getAnimal();
    String makeSound();
}

e uma implementação concretaDuck:

public class Duck implements Animal {

    @Override
    public String getAnimal() {
        return "Duck";
    }

    @Override
    public String makeSound() {
        return "Squeks";
    }
}

Além disso, podemos criar implementações mais concretas da interfaceAnimal (comoDog, Bear, etc.) exatamente dessa maneira.

A Fábrica Abstrata lida com famílias de objetos dependentes. Com isso em mente, vamos apresentar mais uma famíliaColor como uma interface com algumas implementações (White, Brown,…).

Vamos pular o código real por enquanto, mas ele pode ser encontradohere.

Agora que temos várias famílias prontas, podemos criar uma interfaceAbstractFactory para elas:

public interface AbstractFactory {
    T create(String animalType) ;
}

A seguir, implementaremos umAnimalFactory usando o padrão de design Factory Method que discutimos na seção anterior:

public class AnimalFactory implements AbstractFactory {

    @Override
    public Animal create(String animalType) {
        if ("Dog".equalsIgnoreCase(animalType)) {
            return new Dog();
        } else if ("Duck".equalsIgnoreCase(animalType)) {
            return new Duck();
        }

        return null;
    }

}

Da mesma forma, podemos implementar uma fábrica para a interfaceColor usando o mesmo padrão de projeto.

Quando tudo isso estiver definido, criaremos uma classeFactoryProvider que nos fornecerá uma implementação deAnimalFactory ouColorFactory dependendo do argumento que fornecemos aogetFactory() método:

public class FactoryProvider {
    public static AbstractFactory getFactory(String choice){

        if("Animal".equalsIgnoreCase(choice)){
            return new AnimalFactory();
        }
        else if("Color".equalsIgnoreCase(choice)){
            return new ColorFactory();
        }

        return null;
    }
}

3. Quando usar o padrão abstrato de fábrica:

  • O cliente é independente de como criamos e compomos os objetos no sistema

  • O sistema consiste em várias famílias de objetos e essas famílias são projetadas para serem usadas juntas

  • Precisamos de um valor de tempo de execução para construir uma dependência específica

While the pattern is great when creating predefined objects, adding the new ones might be challenging. Para suportar o novo tipo de objeto, será necessário alterar a classeAbstractFactory e todas as suas subclasses.

4. Sumário

Neste artigo, aprendemos sobre o padrão de design Abstract Factory.

Finalmente, como sempre, a implementação desses exemplos pode ser encontradaover on GitHub.