Template Method: Bebida Quente (exemplo): Difference between revisions
From Wiki**3
No edit summary |
No edit summary |
||
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 11: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".