|
|
(8 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
− | O padrão "template method" corresponde à definição do esqueleto de um algoritmo de uma operação em que alguns passos são delegados em subclasses. O padrão permite que as subclasses redefinam partes do algoritmo sem a estrutura do algoritmo seja alterada. | + | {{NAVPO}} |
| + | {{TOCright}} |
| + | O padrão "template method" corresponde à definição do esqueleto de um algoritmo de uma operação em que alguns passos são delegados em subclasses. O padrão permite que as subclasses redefinam partes do algoritmo sem a estrutura do algoritmo seja alterada. |
| | | |
| ==Estrutura== | | ==Estrutura== |
Line 7: |
Line 9: |
| [[Image:templatemethod-dpcd.png|400px]] | | [[Image:templatemethod-dpcd.png|400px]] |
| | | |
− | ==Exemplo== | + | ==Exemplos== |
| | | |
− | Este exemplo aplica o padrão ao "problema" de preparação de uma bebida quente.
| + | * [[Template Method: Bebida Quente (exemplo)|Preparação de bebida quente]] |
− | | + | * [[Template Method: Génios da Lâmpada (exemplo)|Génios da lâmpada]] |
− | 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". | | 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]] |
O padrão "template method" corresponde à definição do esqueleto de um algoritmo de uma operação em que alguns passos são delegados em subclasses. O padrão permite que as subclasses redefinam partes do algoritmo sem a estrutura do algoritmo seja alterada.
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".