• Nenhum resultado encontrado

TemplateMethod 2010 1

N/A
N/A
Protected

Academic year: 2021

Share "TemplateMethod 2010 1"

Copied!
7
0
0

Texto

(1)

Padrões de Projeto

Template Method

Fábio Gondim

Template Method

Intenção [GoF]

“Definir o esqueleto de um algoritmo em uma

operação, postergando alguns passos para as

subclasses. Template Method permite que

subclasses redefinam certos passos de um

algoritmo sem mudar a estrutura do mesmo.”

Resumo

(Fonte: Jacques Philippe Sauvé)

(http://jacques.dsc.ufcg.edu.br/cursos/map/html/pat/template.htm)

– “Um Template Method define um algoritmo

usando operações abstratas”;

– “Subclasses fazem override das operações para

prover um comportamento concreto”;

– “Este padrão é a base para a construção de

frameworks”;

Aplicabilidade [GoF]

O padrão Template Method pode ser usado:

• “Para implementar as partes invariantes de um

algoritmo uma única vez e deixar para as

subclasses a implementação do comportamento

variável”;

• “Quando um comportamento comum entre

subclasses deveria ser fatorado e concentrado

numa classe comum para evitar a duplicação de

código.”;

Aplicabilidade [GoF]

• É um passo freqüente de “refactoring” de

código:

– Primeiro identifique as diferenças no código

existente;

– Separe as diferenças em novas operações

(métodos);

– Substitua o código que apresentava as

diferenças por um método-template que chama

uma dessas novas operações (métodos).

Aplicabilidade [GoF]

• Para controlar extensões de subclasses:

– Você pode definir um Template Method que

chame operações “gancho” (hook) em pontos

específicos, permitindo extensões somente

nestes pontos;

“Faça com que apenas os métodos-gancho possam

sofrer override, usando adjetivos de visibilidade:

- ‘public final’ para o Template Method;

- ‘protected’ para métodos que podem ou devem

sofrer override;”

(2)

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

Café com Leite e Chá com Limão são

preparados de maneira muito

semelhantes:

Receita de Café com Leite

1. Ferver um pouco de água;

2. Misturar o café na água fervente e coá-lo; 3. Servir o café na xícara;

4. Acrescentar açúcar e leite.

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

Café com Leite e Chá com Limão são

preparados de maneira muito

semelhantes:

Receita de Chá com limão

1. Ferver um pouco de água;

2. Colocar o chá em infusão na água fervente; 3. Despejar o chá na xícara;

4. Acrescentar limão.

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

// Implementação inicial sem o padrão template

protected class CafeComLeite {

public void prepararReceita() {

ferverAgua();

misturarCafe();

servirNaXicara();

adicionarAcucarEleite();

}

//...

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

protected void ferverAgua() {

System.out.println(“Fervendo a água”);

}

protected void misturarCafe() {

System.out.println(“Derramando café

no filtro”);

}

// ...

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

protected void servirNaXicara() {

System.out.println(“Servindo na xícara”);

}

protected void adicionarAcucarEleite() {

System.out.println(“Adicionando Açúcar e Leite”);

}

}

// final da classe

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

// Implementação inicial sem o padrão template

public class ChaComLimao {

public void prepararReceita() {

ferverAgua();

misturarCha();

servirNaXicara();

adicionarLimao();

}

//...

(3)

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

protected void ferverAgua() {

System.out.println(“Fervendo a água”);

}

protected void misturarCha() {

System.out.println(“Adicionando a bolsa

de chá”);

}

// ...

Exemplo

Fonte: Use a Cabeça! Padrões de Projeto de Eric Freeman & Elisabeth Freeman

protected void servirNaXicara() {

System.out.println(“Servindo na xícara”);

}

protected void adicionarLimao() {

System.out.println(“Adicionando Limão”);

}

}

// final da classe

Comparando as classes

CafeComLeite e ChaComLimao

Observe que as receitas de chá e café

seguem o mesmo algoritmo:

1. Ferver um pouco de água;

2. Usar a água fervida para extrair e misturar

café ou chá;

3. Despejar a bebida resultante em uma xícara;

4. Acrescentar os condimentos apropriados à

bebida

“O padrão Template Method pode ser usado: ...

- Quando um comportamento comum entre subclasses deveria ser fatorado e concentrado numa classe comum para evitar a duplicação de código.”

...

Comparando as classes Café e Chá

Os métodos

ferverAgua()

e

servirNaXicara()

das duas classes são idênticos:

protected void ferverAgua() {

System.out.println(“Fervendo a água”);

}

protected void servirNaXicara() {

System.out.println(“Servindo na xícara”);

}

(4)

// método da classe Café

public voidprepararReceita(){ ferverAgua(); misturarCafe(); servir(); adicionarAcucarEleite(); } // método da classe Chá

public voidprepararReceita(){ ferverAgua(); misturarCha(); servir(); adicionarLimao(); }

Os métodos

prepararReceita()

das classes Café e Limão

não são iguais mas são muito parecidos.

- Misturar e coar o pó de café não é muito diferente de colocar o saquinho de chá em infusão: na verdade são procedimentos análogos.

- Da mesma forma, adicionar açúcar e leite não é muito diferente de adicionar limão: em ambos os casos estaremos adicionando condimentos à bebida.

// método da classe Café

public void prepararReceita() { ferverAgua(); misturarCafe(); servir(); adicionarAcucarEleite(); } // método da classe Chá

public void prepararReceita() { ferverAgua();

misturarCha();

servir();

adicionarLimao();

}

Procurando compatibilizar para otimizar

// método comum

public void prepararReceita() { ferverAgua();

fazerInfusao();

servir();

adicionarCondimentos();

}

public abstract class BebidaCafeinada {

// não sobrecarregue o “template method”; para evitar // isto, declare o método template como “final”;

public final void prepararReceita() {

ferverAgua();

fazerInfusao(); // Inversão de Controle

servirNaXicara();

adicionarCondimentos(); // Inversão de Controle

}

protected abstract void fazerInfusao(); protected abstract void adicionarCondimentos(); protected void ferverAgua() {

System.out.println("Fervendo a água"); }

protected void servirNaXicara() {

System.out.println("Servindo na xícara"); }

}

Template Method e a Inversão de Controle

• Em um template method, a superclasse

chama as operações de uma subclasse e

não o contrário. Isto é uma estrutura de

inversão de controle a que alguns se

referem como “princípio de Hollywood”

("Don't call us, we'll call you“)(Não nos

ligue, nós ligaremos para você).

public class CafeComLeite extends BebidaCafeinada { protected void fazerInfusao() {

System.out.println("Derramando café no filtro"); }

protected void adicionarCondimentos() {

System.out.println("Adicionando Açúcar e Leite"); }

}

public class ChaComLimao extends BebidaCafeinada { protected void fazerInfusao() {

System.out.println("Adicionando a bolsa de chá"); }

protected void adicionarCondimentos() {

System.out.println("Adicionando Limão"); }

(5)

public class TesteTemplate {

public static void main(String[] args) {

BebidaCafeinada cafe = new CafeComLeite(); BebidaCafeinada cha = new ChaComLimao(); System.out.println("CAFÉ COM LEITE:"); cafe.prepararReceita();

System.out.println("============================"); System.out.println("CHÁ COM LIMÃO:");

cha.prepararReceita(); }

}

CAFÉ COM LEITE:

Fervendo a água

Derramando café no filtro

Servindo na xícara

Adicionando Açúcar e Leite

=========================

CHÁ COM LIMÃO:

Fervendo a água

Adicionando a bolsa de chá

Servindo na xícara

Adicionando Limão

Saída do Programa

Estrutura Genérica

Participantes, Colaborações,

Conseqüências e Considerações

(Fonte: Jacques Philippe Sauvé)

(http://jacques.dsc.ufcg.edu.br/cursos/map/html/pat/template.htm)

Participantes

– ClasseAbstrata

• Define operações abstratas que subclasses

concretas definem para implementar certas etapas do algoritmo;

• Implementa um Template Method definindo o

esqueleto de um algoritmo;

– O Template Method chama várias operações, entre

as quais as operações abstratas da classe.

– ClasseConcreta

• Implementa as operações abstratas para

desempenhar as etapas do algoritmo que tenham comportamento específico a esta subclasse.

Colaborações

– ClasseConcreta depende de ClasseAbstrata

para implementar as partes invariantes do

algoritmo.

(6)

Conseqüências

– Template Methods constituem uma das técnicas

básicas de reuso de código;

• São particularmente importantes em frameworks e bibliotecas de classes para o fatoramento de comportamento comum;

– Template Methods levam a uma inversão de

controle conforme explicado anteriormente;

Conseqüências

– O Template Method pode chamar vários tipos de

operações:

• Operações concretas (da ClasseConcreta ou de outras classes)

• Operações concretas de ClasseAbstrata (operações comuns úteis às subclasses)

• Operações abstratas (onde o comportamento varia) – Devem ser sobrescritos (override)

• Factory Methods (assunto que será abordado posteriormente)

• Operações-gancho

– Ver explicação em slide posterior.

Considerações de Implementação

– É importante minimizar o número de operações

abstratas que devem sofrer override para completar

o algoritmo;

• Motivo: simplificação para não chatear o programador

– Convenções de nome:

• Métodos abstratos que devem sofrer override deveriam ter algo de comum no nome

– Exemplo: doXpto() // começa com "do"

• Métodos-gancho que podem sofrer override deveriam ter algo de comum no nome

– Exemplo: logHook() // termina com "Hook"

Operações-gancho (hook operations):

“Fornecem comportamento padrão que subclasses

podem estender se necessário. Uma operação gancho frequentemente não executa nada por padrão.” [GoF]

As operações-gancho, declaradas na superclasse abstrata, não devem ser abstratas, pois as subclasse não devem ser obrigas a implementá-la. Os métodos ganchos só serão sobrescritos pelas subclasses em que forem necessários. Se não houver

comportamento padrão a implementar deverão ser vazios na superclasse.

public void gancho() { }

// Implementado um método-gancho public abstract class BebidaCafeinada {

public final void prepararReceita() {

ferverAgua(); fazerInfusao(); servirNaXicara(); adicionarCondimentos();

gancho(); // Algumas subclasses irão sobrescrever // Quem não sobrescrever não estenderá o comportamento

}

protected abstract void fazerInfusao(); protected abstract void adicionarCondimentos(); protected void ferverAgua() {

System.out.println("Fervendo a água"); }

protected void servirNaXicara() {

System.out.println("Servindo na xícara"); }

protected void gancho() { }

Se você executar a classe TesteTemplate não irá

acontecer nada de diferente porque ninguém

sobrescreveu o método-gancho().

Exercício:

1 - Crie uma classe adicional que sobrescreva o

método-gancho e adicione novo(s)

comportamento(s);

2 – Faça o diagrama de classes do exemplo que

acabamos de implementar.

(7)

Exercício

Já temos o café.

Que tal um bolo de chocolate para acompanhar o café!

INGREDIENTES:

2 xícaras de farinha de trigo; 2 xícaras de açúcar; 1 xícara de leite;

6 colheres de sopa cheias de chocolate em pó; 1 colher de sopa de fermento em pó; 6 ovos.

Receita do Bolo de

Chocolate com Cobertura

1. Bata as claras em neve, acrescente as gemas e bate

novamente, coloque o açúcar (ou adoçante se for um bolo diet) e bata outra vez;

2. Coloque a farinha, o chocolate em pó, o fermento, o leite e bata novamente;

3. Untar um tabuleiro e colocar para assar por aproximadamente 40 minutos em forno médio; 4. Enquanto o bolo assa faça a cobertura com 2 colheres

de chocolate em pó, 1 colher de margarina, meio copo de leite e leve ao fogo até começar a ferver;

5. Jogue a cobertura quente sobre o bolo já assado.

Exercício

Considerando:

1. Que cada passo da receita (itens de 1 a 5) seja representado por um método com comandos simples (instruções println’s);

2. Que queremos fazer três bolos de chocolate: um com cobertura e outro sem cobertura (ambos com açúcar) e um terceiro com adoçante e sem cobertura;

Pede-se:

A partir de um design que utilize o padrão Template Method para resolver o problema levantado (faça o diagrama de classes no Jude), escreva o correspondente código em java de todas as classes envolvidas inclusive a classe cliente (teste) que conterá o método main(). Note que no template method, adoçar é um comportamento variável e que fazer e colocar a cobertura são opcionais.

Bibliografia

– GAMMA, E., HELM, R., JOHNSON, R. e VLISSIDES, J.

Padrões de Projeto – Soluções reutilizáveis de software orientado a obetos. Bookman. 1995;

– FREEMAN, Eric, FREEMAN, Elizabeth. Use a Cabeça!

– Padrões de Projeto, Alta Books. 2005;

– LARMAN, Craig. Utilizando UML e Padrões. 2. ed. Bookman. 2002;

– http://jacques.dsc.ufcg.edu.br/cursos/map/html/pat/temp late.htm;

Referências

Documentos relacionados

This retrospective study assessed early, clinical and X-ray outcomes using this technique and the total metal-on-metal resurfacing prosthesis3. MATERIALS

Convencionam as partes que, exclusivamente para os empregados que mantêm contrato de trabalho com a mesma empresa ou, empresa do mesmo grupo econômico há mais de 10 (dez) anos e

78 Figura 3.27 Padrão de difração de pós obtido para o complexo ácido nalidíxico:Zn através (a) de síntese por solução, em comparação com os difractogramas

Para reduzir o consumo de energia eléctrica, água ou gás, não use o aparelho em vazio ou em condições que comprometam o rendimento máximo (por ex. portas ou tampas abertas, etc.);

The choice of solvent, an ethyl-ester of ricinoleic acid or castor-oil based biodiesel, was elaborated in previous work (Zautsen et al., 2011a) and based on the

Sempre que as entidades adjudicantes recorrerem à possibilidade prevista no n.º 3, alínea a), de formular especificações técnicas em termos de desempenho ou de

Resultados obtidos no levantamento realizado 66 dias após a aplicação, mediante o desdobramento da interação dosagem x espalhante-adesivo mostraram que o cyhe- xatin, na dosagem

O LAVI vem sendo montado gradativamente, com recursos provenientes do FDA (Fundo de Desenvolvimento Acadêmico) e LABGRAD (Programa de Apoio aos Laboratórios de