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

From Wiki**3

(New page: 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ã...)
 
(Terceiro Cenário: Aplicação do Padrão Template Method)
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
 
Este exemplo mostra a aplicação do padrão ''template method'' ao "problema" de preparação de uma bebida quente.
 
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''.
+
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 ==
 
== 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.
 
Na situação inicial há repetição de código e não há abstracção de conceitos comuns nem, por isso, reutilização.
 
+
<source lang="java">
 
   public class Café {
 
   public class Café {
 
    
 
    
 
     void preparar() {
 
     void preparar() {
       ferverÁgua();
+
       ferverÁgua();
       juntarGrãosMoídos();
+
       juntarGrãosMoídos();
 
       despejarNaChávena();
 
       despejarNaChávena();
 
       juntarAçúcar();
 
       juntarAçúcar();
Line 19: Line 18:
 
     // &c.
 
     // &c.
 
   }
 
   }
 +
</source>
  
 +
<source lang="java">
 
   public class Chá {
 
   public class Chá {
 
    
 
    
 
     void preparar() {
 
     void preparar() {
       ferverÁgua();
+
       ferverÁgua();
 
       juntarFolhas();
 
       juntarFolhas();
 
       despejarNaChávena();
 
       despejarNaChávena();
Line 31: Line 32:
 
     // &c.
 
     // &c.
 
   }
 
   }
 +
</source>
  
=== Segundo Cenário: Abstracção de Características Comuns ===
+
== 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.
+
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.
  
 +
<source lang="java">
 
   public abstract class BebidaQuente {
 
   public abstract class BebidaQuente {
 
 
 
     abstract void preparar();
 
     abstract void preparar();
 
    
 
    
     void ferverÁgua()        { /* faz coisas */ }
+
     void ferverÁgua()        { /* faz coisas */ }
 
     void despejarNaChávena() { /* faz coisas */ }
 
     void despejarNaChávena() { /* faz coisas */ }
 
   }
 
   }
 
+
</source>
 +
<source lang="java">
 
   public class Café extends BebidaQuente {
 
   public class Café extends BebidaQuente {
 
+
     void juntarGrãosMoídos() { /* faz coisas */ }
     void juntarGrãosMoídos() { /* faz coisas */ }
 
 
     void juntarAçúcar()      { /* faz coisas */ }
 
     void juntarAçúcar()      { /* faz coisas */ }
 
    
 
    
 
     void preparar() { /* como antes */ }
 
     void preparar() { /* como antes */ }
 
   }
 
   }
 
+
</source>
 +
<source lang="java">
 
   public class Chá extends BebidaQuente {
 
   public class Chá extends BebidaQuente {
 
 
 
     void juntarFolhas() { /* faz coisas */ }
 
     void juntarFolhas() { /* faz coisas */ }
 
     void juntarLimão()  { /* faz coisas */ }
 
     void juntarLimão()  { /* faz coisas */ }
Line 59: Line 61:
 
     void preparar() { /* como antes */ }
 
     void preparar() { /* como antes */ }
 
   }
 
   }
 +
</source>
  
=== 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).
 +
<source lang="java">
 
   public abstract class BebidaQuente {
 
   public abstract class BebidaQuente {
 
     abstract void infundir();
 
     abstract void infundir();
Line 69: Line 72:
 
    
 
    
 
     void preparar() {
 
     void preparar() {
       ferverÁgua();
+
       ferverÁgua();
 
       infundir();
 
       infundir();
 
       despejarNaChávena();
 
       despejarNaChávena();
Line 75: Line 78:
 
     }
 
     }
 
    
 
    
     void ferverÁgua()        { /* faz coisas */ }
+
     void ferverÁgua()        { /* faz coisas */ }
 
     void despejarNaChávena() { /* faz coisas */ }
 
     void despejarNaChávena() { /* faz coisas */ }
 
   }
 
   }
 
+
</source>
 +
<source lang="java">
 
   class Café extends BebidaQuente {
 
   class Café extends BebidaQuente {
     // void juntarGrãosMoídos() { /* faz coisas */ }
+
     // void juntarGrãosMoídos() { /* faz coisas */ }
 
     // void juntarAçúcar()      { /* faz coisas */ }
 
     // void juntarAçúcar()      { /* faz coisas */ }
     public void infundir()    { /* juntar grãos moídos */ }
+
     public void infundir()    { /* juntar grãos moídos */ }
 
     public void condimentar() { /* juntar açúcar      */ }
 
     public void condimentar() { /* juntar açúcar      */ }
 
   }
 
   }
 
+
</source>
 +
<source lang="java">
 
   class Chá extends BebidaQuente {
 
   class Chá extends BebidaQuente {
 
     // void juntarFolhas() { /* faz coisas */ }
 
     // void juntarFolhas() { /* faz coisas */ }
Line 92: Line 97:
 
     public void condimentar() { /* juntar limão  */ }
 
     public void condimentar() { /* juntar limão  */ }
 
   }
 
   }
 +
</source>
  
 
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".
  
[[category:OOP]]
+
[[category:Ensino]]
[[category:Teaching]]
+
[[category:PO]]
 +
[[category:PO Exemplos]]
 +
[[category:Java]]

Latest revision as of 17:18, 24 November 2020

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.

  public class Café {
  
    void preparar() {
      ferverÁgua();
      juntarGrãosMoídos();
      despejarNaChávena();
      juntarAçúcar();
    }
  
    // &c.
  }
  public class Chá {
  
    void preparar() {
      ferverÁgua();
      juntarFolhas();
      despejarNaChávena();
      juntarLimão();
    }
  
    // &c.
  }

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.

  public abstract class BebidaQuente {
    abstract void preparar();
  
    void ferverÁgua()        { /* faz coisas */ }
    void despejarNaChávena() { /* faz coisas */ }
  }
  public class Café extends BebidaQuente {
    void juntarGrãosMoídos() { /* faz coisas */ }
    void juntarAçúcar()      { /* faz coisas */ }
  
    void preparar() { /* como antes */ }
  }
  public class Chá extends BebidaQuente {
    void juntarFolhas() { /* faz coisas */ }
    void juntarLimão()  { /* faz coisas */ }
  
    void preparar() { /* como antes */ }
  }

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

  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 */ }
  }
  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       */ }
  }
  class Chá extends BebidaQuente {
    // void juntarFolhas() { /* faz coisas */ }
    // void juntarLimão()  { /* faz coisas */ }
    public void infundir()    { /* juntar folhas */ }
    public void condimentar() { /* juntar limão  */ }
  }

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