Matheus Tardivo

Thinking and talking about software development

Archive for novembro \01\UTC 2007

Don’t call us, we’ll call you.

Posted by Matheus Tardivo em novembro 1, 2007

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.

Basicamente, o padrão consiste na criação de um template para o algoritmo. Mas o que é um template? É apenas um método – ou, mais especificamente, é um método que define um algoritmo como uma seqüência de passos. Um ou mais desses passos podem ser definidos como abstratos e implementados por uma subclasse. Isto assegura que a estrutura do algoritmo permaneça inalterada mesmo quando as subclasses fornecem parte da implementação.

Verifiquemos o diagrama de classes:
TemplateMethod

  • A ClasseAbstrata contém o template method e versões abstratas das operações usadas no template method.
  • O template method utiliza operações primitivas para implementar um algoritmo, mas desconectada da implementação efetiva dessas operações.
  • A ClasseConcreta implementa as operações abstratas, que são chamadas quando o templateMethod() precisa delas.
  • Podem existir muitas classes concretas, cada uma implementando o conjunto de operações exigidas pelo template method.

E o código:
ClasseAbstrata

public abstract class ClasseAbstrata {

	public final void templateMethod() {
		operacaoPrimitiva1();
		operacaoPrimitiva2();
		operacaoConcreta1();
		operacaoConcreta2();
	}

	public abstract void operacaoPrimitiva1();

	public abstract void operacaoPrimitiva2();

	public void operacaoConcreta1() {
		// implementação
	}

	public void operacaoConcreta2() {
		// implementação
	}
}

ClasseConcreta

public class ClasseConcreta extends ClasseAbstrata {

	public void operacaoPrimitiva1() {
		// implementação da operação primitiva 1
	}

	public void operacaoPrimitiva2() {
		// implementação da operação primitiva 1
	}
}

Usando:

ClasseAbstrata classe = new ClasseConcreta();
classe.templateMethod();

Uma forma de controle das extensões de subclasses são os métodos gancho (hook methods, em inglês). É possível então criar um template method que chama os métodos gancho, permitindo um controle do comportamento somente nestes pontos.

Agora um código de exemplo usando o gancho:

public abstract class ClasseAbstrata {

	public final void templateMethod() {
		// Agora a operação está condicionada ao gancho.
		if (gancho()) {
			operacaoPrimitiva1();
		}
		operacaoPrimitiva2();
		operacaoConcreta1();
		operacaoConcreta2();
	}

	public abstract void operacaoPrimitiva1();

	public abstract void operacaoPrimitiva2();

	public void operacaoConcreta1() {
		// implementação
	}

	public void operacaoConcreta2() {
		// implementação
	}

	// Por padrão, o gancho apenas retorna true.
	public boolean gancho() {
		return true;
	}
}

As subclasses podem ou não sobrescrever o gancho. Devem fazer isso apenas se desejam mudar o comportamento padrão, como por exemplo, adicionar alguma condição para a execução da operacaoPrimitiva1.
Exemplo:

public class ClasseConcreta extends ClasseAbstrata {

	public void operacaoPrimitiva1() {
		// implementação da operação primitiva 1
	}

	public void operacaoPrimitiva2() {
		// implementação da operação primitiva 1
	}

	@Override
	public boolean gancho() {
		// Faz alguma verificação
		if (...) {
			return true;
		}

		return false;
	}
}

Mas você deve estar se perguntando: “O que o título deste post tem haver com esse padrão?”. A resposta é simples: muito!
Este título é o Princípio de Hollywood, que traduzido significa: Não nos telefone, nós telefonaremos para você.

O Princípio de Hollywood nos proporciona uma maneira de evitar o “colapso das dependências”. Colapso das dependências é o que acontece quando você tem componentes de alto nível dependendo de componentes de baixo nível que dependem de componentes de alto nível que dependem de componentes laterais que dependem de componentes de baixo nível, e assim por diante (ufa). Quando essa estrutura entra em colapso, ninguém mais consegue entender como o sistema foi originalmente projetado.

Com o Princípio de Hollywood, nós permitimos que componentes de baixo nível se conectem ao sistema através de ganchos, mas são os componentes de alto nível que determinam quando e como eles serão solicitados. Em outras palavras, os componentes de alto nível dizem aos componentes de baixo nível: “Não nos telefone, nós telefonaremos para você.”

É provável que você já tenha detectado a conexão entre o Princípio de Hollywood e o Template method: quando usamos um template method, na verdade estamos dizendo às subclasses: “não nos telefone, nós telefonaremos para vocês”.

Anúncios

Posted in Java, padrões de projeto | 1 Comment »

O meu chefe tem um jatinho. O seu também tem?

Posted by Matheus Tardivo em novembro 1, 2007

Mais uma thread para entrar na história do GUJ. A intenção do tópico era de anunciar o framework Space4J que tem como objetivo “ser um banco de dados simples que vai te permitir trabalhar com Java Collections em memória”.

Acontece que, para dar continuidade a tradição, o assunto do tópico mudou de rumo. Mas, na minha opinião, para um rumo interessante.
A essência da discussão gira em torno de: qual é a verdadeira importância de um projeto ter uma suíte de testes? Mais uma vez, na minha opinião, é MUITO importante para qualquer projeto ter uma suíte de testes.

A maioria dos projetos que trabalhei não tinham uma suíte de testes – apesar de eu não me conformar com isso e desenvolver testes para partes isoladas. O que eu não me engano é da importância que eles representam para um projeto. Como já foi falado, boas práticas de orientação a objetos e “programação defensiva” (!) não basta para garantir que algo que estava funcionando, deixe repentinamente de funcionar por alterações que o sistema sofreu.

Vale a pena ler sobre Test-driven development e Behavior driven development. Mas é bom deixar claro que existe uma grande diferença entre fazer Test-Driven Development e testar. “TDD é sobre modelagem de objetos e especificações, não sobre testes (tanto que Behaviour Driven Development está se consolidando como algo mais eficiente que TDD) apesar de que no final você acaba ganhando uma suíte de testes de graça.” (trecho retirado do post do Phillip – veja o final deste post).

Outra coisa que sempre acontece nesse tipo de discussão são as pérolas que surgem. Para justificar a ausência dos testes, as pessoas apelam pra todo tipo de absurdo: “em um mundo capitalizado não há tempo para testes”, “não agrega nada para o cliente”, ou até mesmo uma das maiores pérolas que já vi: “Agora, se me permite, vou voltar ao trabalho, pois o meu chefe, que também gosta do (coloque aqui um framework sem testes) e tem o seu próprio jato particular e não está nem um pouco preocupado com os testes unitários…”

Deixando um pouco o circo de lado, toda essa discussão incentivou mais um ótimo post do Phillip Calçado – que aliás, está de malas prontas para trabalhar na ThoughtWorks. Leiam: Programadores Profissionais Escrevem Testes, Ponto Final.

Posted in pérolas, testes | 1 Comment »