Difference between revisions of "Template Method: Bebida Quente (exemplo)"

From Wiki**3

Line 6: Line 6:
  
 
Na situação inicial há repetição de código e não há abstracção de conceitos comuns nem, por isso, reutilização.
 
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é {
 
   public class Café {
 
    
 
    
Line 18: Line 18:
 
     // &c.
 
     // &c.
 
   }
 
   }
 +
</java5>
  
 +
<java5>
 
   public class Chá {
 
   public class Chá {
 
    
 
    
Line 30: Line 32:
 
     // &c.
 
     // &c.
 
   }
 
   }
 +
</java5>
  
 
== Segundo Cenário: Abstracção de Características Comuns ==
 
== Segundo Cenário: Abstracção de Características Comuns ==
Line 35: Line 38:
 
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.
 
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 {
 
   public abstract class BebidaQuente {
 
    
 
    
Line 42: Line 46:
 
     void despejarNaChávena() { /* faz coisas */ }
 
     void despejarNaChávena() { /* faz coisas */ }
 
   }
 
   }
 
+
</java5>
 +
<java5>
 
   public class Café extends BebidaQuente {
 
   public class Café extends BebidaQuente {
 
    
 
    
Line 50: Line 55:
 
     void preparar() { /* como antes */ }
 
     void preparar() { /* como antes */ }
 
   }
 
   }
 
+
</java5>
 +
<java5>
 
   public class Chá extends BebidaQuente {
 
   public class Chá extends BebidaQuente {
 
    
 
    
Line 58: Line 64:
 
     void preparar() { /* como antes */ }
 
     void preparar() { /* como antes */ }
 
   }
 
   }
 +
</java5>
  
 
== Terceiro Cenário: Aplicação do Padrão Template Method ==
 
== 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).
 
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 {
 
   public abstract class BebidaQuente {
 
     abstract void infundir();
 
     abstract void infundir();
Line 77: Line 84:
 
     void despejarNaChávena() { /* faz coisas */ }
 
     void despejarNaChávena() { /* faz coisas */ }
 
   }
 
   }
 
+
</java5>
 +
<java5>
 
   class Café extends BebidaQuente {
 
   class Café extends BebidaQuente {
 
     // void juntarGrãosMoídos() { /* faz coisas */ }
 
     // void juntarGrãosMoídos() { /* faz coisas */ }
Line 84: Line 92:
 
     public void condimentar() { /* juntar açúcar      */ }
 
     public void condimentar() { /* juntar açúcar      */ }
 
   }
 
   }
 
+
</java5>
 +
<java5>
 
   class Chá extends BebidaQuente {
 
   class Chá extends BebidaQuente {
 
     // void juntarFolhas() { /* faz coisas */ }
 
     // void juntarFolhas() { /* faz coisas */ }
Line 91: Line 100:
 
     public void condimentar() { /* juntar limão  */ }
 
     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".
 
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".

Revision as of 13:45, 6 November 2008

Este exemplo mostra a aplicação do padrão template method ao "problema" de preparação de uma bebida quente.

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".