Introdução

A ideia inicial de padrão de projeto surgiu em 1977 com Christopher Alexander na área de Arquitetura (prédios e cidades). Seus livros e suas ideias foram usados de inspiração para os desenvolvedores de software. Além da arquitetura e do desenvolvimento de software, outras áreas como a Química e as áreas da Engenharia também possuem catálogos de soluções para problemas recorrentes.

Na área do desenvolvimento de software existe um catálogo de soluções desde 1995 com o livro "Design Patterns - Elements of Reusable Object-Oriented Software". Seus idealizadores foram Gamma, Helm, Johnson e Vlissides. Nesse livro são descritos diversos Padrões de Projetos.

Com o catálogo de Padrões de Projetos passamos a ter um vocabulário em comum, soluções descritas e com nomes descritivos, entre diversas outras vantagens.

Padrões de Projetos normalmente possuem Nome, Problema, Solução e Consequências/Forças.

Neste artigo veremos mais sobre o Padrão de projeto Template Method que é utilizado em diversos projetos e API's do Java.

Funcionamento

O Padrão de Projeto Template Method define os passos de um algoritmo e permite que a implementação de um ou mais desses passos seja fornecida por subclasses. Assim, o Template Method protege o algoritmo e fornece métodos abstratos para que as subclasses possam implementá-los.

A definição oficial do padrão Template Method é: “O Padrão Template Method define o esqueleto de um algoritmo dentro de um método, transferindo alguns de seus passos para as subclasses. O Template Method permite que as subclasses redefinam certos passos de um algoritmo sem alterar a estrutura do próprio algoritmo”.

Portanto, o padrão Template Method basicamente oferece um método que define um algoritmo (uma sequência de passos) que pode, por sua vez, ser definido como abstrato para posteriormente ser implementado por uma subclasse. Pode-se notar que a estrutura do algoritmo fica inalterada mesmo com as subclasses fazendo parte da implementação.

O Diagrama de classe abaixo mostra mais detalhes sobre o funcionamento do padrão Template Method.

Diagrama de classe do Padrão Template Method

Figura 1: Diagrama de classe do Padrão Template Method

No diagrama de classe acima temos a classe AbstractClass contendo o método “templateMethod()” que possui o algoritmo e quel define os métodos “primitiveOperation1()” e “primitiveOperation2()” que são abstratos. As classes concretas Concrete1 e Concrete2 implementam os métodos abstratos que serão chamados quando “templateMethod()” precisar delas. Vale salientar que o método “templateMethod()” é final, ou seja, ele não pode ser sobrescrito, seu algoritmo não pode ser mexido. Já os métodos “primitiveOperation1()” e “primitiveOperation2()” podem ser sobrescritos. Além disso, ainda poderíamos ter um método concreto ou ainda um método final que não poderia ser sobrescrito e seria utilizado no algoritmo do templateMethod(). Isso ficará mais claro no exemplo de implementação abaixo.

Exemplo de Implementação

Segue abaixo um exemplo de implementação em Java utilizando o Padrão Template Method.

Listagem 1: Exemplo de implementação do Padrão Template Method


public abstract class Treinos {

	final void treinoDiario() {
		preparoFisico();
		jogoTreino();
		treinoTatico();
	}

	abstract void preparoFisico();
	abstract void jogoTreino();
		
	final void treinoTatico() {
		System.out.println("Treino Tatico");
	}

}

class TreinoNoMeioDaTemporada extends Treinos {

	void preparoFisico() {
		System.out.println("Preparo Fisico Intenso.");
	}

	void jogoTreino() {
		System.out.println("Jogo Treino com Equipe Reserva.");
	}
}

class TreinoNoInicioDaTemporada extends Treinos {

	void preparoFisico() {
		System.out.println("Preparo Fisico Leve.");
	}

	void jogoTreino() {
		System.out.println("Jogo Treino com Equipe Junior.");
	}

} 

No exemplo acima temos a classe principal “Treinos” que tem o método “treinoDiario()” que tem como principal finalidade ser um algoritmo a ser seguido por todas as outras classes que estenderem essa classe. Este método é final e não pode ser alterado, todos os treinos devem seguir estas etapas. No entanto, as classes “TreinoNoMeioDaTemporada” e “TreinoNoInicioDaTemporada” implementam os métodos abstratos “preparoFisico()” e “jogotreino()”. Ambos estes métodos podem ser alterados dependendo se o treino está sendo feito no inicio de uma temporada ou no meio dela. Assim, cada método é implementado por sua classe especifica, mas sempre seguindo o algoritmo. O método “treinoTatico()” é definido pelo algoritmo e pela classe base, este método é concreto e final, portanto não pode ser alterado e é seguido por todos os treinamentos. Nada impede também de termos métodos concretos que podem ser sobrescritos nas subclasses ou que simplesmente podem ser usados da sua classe base.

Utilização do Template Method nas API’s Java

O Padrão Template Method também é utilizado nas API’s do Java, como na API Swing onde a classe JFrame define o método paint() como abstrato para ser implementado nas subclasses que estendem JFrame. A substituição do conteúdo de paint() permite que você se conecte ao algoritmo de JFrame para exibir sua área da tela e incorporar a sua própria saída gráfica ao JFrame. Os Applets também utilizam o padrão Template Method através dos métodos init(), start(), stop(), destroy(), e outros.

Conclusão

O Padrão Template Method nos permite reutilizar código sem perder o controle do nossos algoritmos. No Template Method são definidos passos de um algoritmo, permitindo que alguns desses passos sejam implementados por subclasses. Na classe abstrata temos métodos abstratos, concretos e finais. O Template Method é bastante utilizado inclusive na API Java, como pudemos constatar.

Bibliografia

  • Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra. Head First Design Patterns. O'Reilly Media, 2004.
  • Gamma, E., Helm, R., Johnson, R., Vlissides, J. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley, 2010.