Implementando o padrão de método de modelo em Java

Implementando o padrão de método de modelo em Java

1. Visão geral

Neste tutorial rápido, veremos como aproveitar otemplate method pattern - um dos padrõesGoF mais populares.

Torna mais fácil implementar algoritmos complexos, encapsulando a lógica em um único método.

2. Implementação

Para demonstrar como o padrão do método do modelo funciona, vamos criar um exemplo simples que representa a construção de uma estação de computador.

Dada a definição do padrão,the algorithm’s structure will be defined in a base class that defines the template build() method:

public abstract class ComputerBuilder {

    // ...

    public final Computer buildComputer() {
        addMotherboard();
        setupMotherboard();
        addProcessor();
        return new Computer(computerParts);
    }

    public abstract void addMotherboard();
    public abstract void setupMotherboard();
    public abstract void addProcessor();

    // ...
}

The ComputerBuilder class is responsible for outlining the steps required to build a computer by declaring methods for adding and setting up different components, como uma placa-mãe e um processador.

Aqui,the build() method is the template method, que define as etapas do algoritmo para montar as partes do computador e retorna instânciasComputer totalmente inicializadas.

Observe que it’s declared as final to prevent it from being overridden.

3. Em ação

Com a classe base já definida, vamos tentar usá-la criando duas subclasses. Um que constrói um computador "padrão" e o outro que constrói um computador "high-end":

public class StandardComputerBuilder extends ComputerBuilder {

    @Override
    public void addMotherboard() {
        computerParts.put("Motherboard", "Standard Motherboard");
    }

    @Override
    public void setupMotherboard() {
        motherboardSetupStatus.add(
          "Screwing the standard motherboard to the case.");
        motherboardSetupStatus.add(
          "Pluging in the power supply connectors.");
        motherboardSetupStatus.forEach(
          step -> System.out.println(step));
    }

    @Override
    public void addProcessor() {
        computerParts.put("Processor", "Standard Processor");
    }
}

E aqui está a varianteHighEndComputerBuilder:

public class HighEndComputerBuilder extends ComputerBuilder {

    @Override
    public void addMotherboard() {
        computerParts.put("Motherboard", "High-end Motherboard");
    }

    @Override
    public void setupMotherboard() {
        motherboardSetupStatus.add(
          "Screwing the high-end motherboard to the case.");
        motherboardSetupStatus.add(
          "Pluging in the power supply connectors.");
        motherboardSetupStatus.forEach(
          step -> System.out.println(step));
    }

    @Override
    public void addProcessor() {
         computerParts.put("Processor", "High-end Processor");
    }
}

Como podemos ver, não precisamos nos preocupar com todo o processo de montagem, mas apenas em fornecer implementações para métodos separados.

Agora, vamos ver em ação:

new StandardComputerBuilder()
  .buildComputer();
  .getComputerParts()
  .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v));

new HighEndComputerBuilder()
  .buildComputer();
  .getComputerParts()
  .forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v));

4. Métodos de modelo em bibliotecas Java Core

Este padrão é amplamente usado nas bibliotecas principais do Java, por exemplo, porjava.util.AbstractList oujava.util.AbstractSet.

Por exemplo,Abstract List fornece uma implementação esquelética da interfaceList.

Um exemplo de método de modelo pode ser o métodoaddAll(), embora não seja explicitamente definido comofinal:

public boolean addAll(int index, Collection c) {
    rangeCheckForAdd(index);
    boolean modified = false;
    for (E e : c) {
        add(index++, e);
        modified = true;
    }
    return modified;
}

Os usuários só precisam implementar o métodoadd():

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

Aqui, é responsabilidade do programador fornecer uma implementação para adicionar um elemento à lista no índice fornecido (a parte variante do algoritmo de listagem).

5. Conclusão

Neste artigo, mostramos o padrão do método de modelo e como implementá-lo em Java.

O padrão do método de modelo promove a reutilização e dissociação do código, mas às custas do uso da herança.

Como sempre, todos os exemplos de código mostrados neste artigo estão disponíveisover on GitHub.