|
|
Line 1: |
Line 1: |
| Este exemplo mostra a aplicação do padrão ''template method'' ao "problema" de preparação de uma bebida quente.
| | #REDIRECT [[ist:Template Method: Bebida Quente (exemplo)]] |
| | |
| Este exemplo mostra a evolução de uma aplicação à medida que são aplicadas técnicas de programação com objectos, em que se refactoriza algum código, e de aplicação de padrões, neste caso, o ''template method''.
| |
| | |
| == Situação Inicial ==
| |
| | |
| Na situação inicial há repetição de código e não há abstracção de conceitos comuns nem, por isso, reutilização.
| |
| <java5>
| |
| public class Café {
| |
|
| |
| void preparar() {
| |
| ferverÁgua();
| |
| juntarGrãosMoídos();
| |
| despejarNaChávena();
| |
| juntarAçúcar();
| |
| }
| |
|
| |
| // &c.
| |
| }
| |
| </java5>
| |
| | |
| <java5>
| |
| public class Chá {
| |
|
| |
| void preparar() {
| |
| ferverÁgua();
| |
| juntarFolhas();
| |
| despejarNaChávena();
| |
| juntarLimão();
| |
| }
| |
|
| |
| // &c.
| |
| }
| |
| </java5>
| |
| | |
| == Segundo Cenário: Abstracção de Características Comuns ==
| |
| | |
| Nesta situação abstrairam-se algumas das características comuns e procurou-se reutilizar o máximo de funcionalidade. Note-se que, ainda assim, há repetição da estrutura do "algoritmo" de aquecimento.
| |
| | |
| <java5>
| |
| public abstract class BebidaQuente {
| |
| abstract void preparar();
| |
|
| |
| void ferverÁgua() { /* faz coisas */ }
| |
| void despejarNaChávena() { /* faz coisas */ }
| |
| }
| |
| </java5>
| |
| <java5>
| |
| public class Café extends BebidaQuente {
| |
| void juntarGrãosMoídos() { /* faz coisas */ }
| |
| void juntarAçúcar() { /* faz coisas */ }
| |
|
| |
| void preparar() { /* como antes */ }
| |
| }
| |
| </java5>
| |
| <java5>
| |
| public class Chá extends BebidaQuente {
| |
| void juntarFolhas() { /* faz coisas */ }
| |
| void juntarLimão() { /* faz coisas */ }
| |
|
| |
| void preparar() { /* como antes */ }
| |
| }
| |
| </java5>
| |
| | |
| == Terceiro Cenário: Aplicação do Padrão Template Method ==
| |
| | |
| Manteve-se a abstracção conseguida no segundo cenário e aplicou-se o padrão template method. O resultado é o desaparecimento do algoritmo repetido: agora aparece apenas na superclasse e as partes dependentes das subclasses são definidas por cada uma. Note-se que a interface é agora imposta pela superclasse e que pode haver necessidade de renomear alguns dos métodos existentes (ou, alternativamente, de os chamar a partir dos que implementam a interface devida à aplicação do padrão).
| |
| <java5>
| |
| public abstract class BebidaQuente {
| |
| abstract void infundir();
| |
| abstract void condimentar();
| |
|
| |
| void preparar() {
| |
| ferverÁgua();
| |
| infundir();
| |
| despejarNaChávena();
| |
| condimentar();
| |
| }
| |
|
| |
| void ferverÁgua() { /* faz coisas */ }
| |
| void despejarNaChávena() { /* faz coisas */ }
| |
| }
| |
| </java5>
| |
| <java5>
| |
| class Café extends BebidaQuente {
| |
| // void juntarGrãosMoÃdos() { /* faz coisas */ }
| |
| // void juntarAçúcar() { /* faz coisas */ }
| |
| public void infundir() { /* juntar grãos moÃdos */ }
| |
| public void condimentar() { /* juntar açúcar */ }
| |
| }
| |
| </java5>
| |
| <java5>
| |
| class Chá extends BebidaQuente {
| |
| // void juntarFolhas() { /* faz coisas */ }
| |
| // void juntarLimão() { /* faz coisas */ }
| |
| public void infundir() { /* juntar folhas */ }
| |
| public void condimentar() { /* juntar limão */ }
| |
| }
| |
| </java5>
| |
| | |
| A chamada pela superclasse de métodos definidos nas subclasses é uma aplicação do chamado "Hollywood Principle", i.e., "don't call us, we'll call you".
| |
| | |
| [[category:Ensino]]
| |
| [[category:PO]]
| |
| [[category:PO Exemplos]]
| |
| [[category:Java]]
| |