(→Terceiro Cenário: Aplicação do Padrão Template Method) |
|||
(5 intermediate revisions by the same user not shown) | |||
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. | ||
− | < | + | <source lang="java"> |
public class Café { | public class Café { | ||
void preparar() { | void preparar() { | ||
ferverÁgua(); | ferverÁgua(); | ||
− | + | juntarGrãosMoídos(); | |
despejarNaChávena(); | despejarNaChávena(); | ||
juntarAçúcar(); | juntarAçúcar(); | ||
Line 18: | Line 18: | ||
// &c. | // &c. | ||
} | } | ||
− | </ | + | </source> |
− | < | + | <source lang="java"> |
public class Chá { | public class Chá { | ||
Line 32: | Line 32: | ||
// &c. | // &c. | ||
} | } | ||
− | </ | + | </source> |
== Segundo Cenário: Abstracção de Características Comuns == | == Segundo Cenário: Abstracção de Características Comuns == | ||
Line 38: | 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. | ||
− | < | + | <source lang="java"> |
public abstract class BebidaQuente { | public abstract class BebidaQuente { | ||
− | |||
abstract void preparar(); | abstract void preparar(); | ||
Line 46: | Line 45: | ||
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 | ||
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 64: | 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 84: | Line 81: | ||
void despejarNaChávena() { /* faz coisas */ } | void despejarNaChávena() { /* faz coisas */ } | ||
} | } | ||
− | </ | + | </source> |
− | < | + | <source lang="java"> |
class Café extends BebidaQuente { | class Café extends BebidaQuente { | ||
− | // void | + | // void juntarGrãosMoídos() { /* faz coisas */ } |
// void juntarAçúcar() { /* faz coisas */ } | // void juntarAçúcar() { /* faz coisas */ } | ||
− | public void infundir() { /* juntar grãos | + | 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 100: | 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: | + | [[category:Ensino]] |
− | [[category: | + | [[category:PO]] |
+ | [[category:PO Exemplos]] | ||
+ | [[category:Java]] |
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.
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.
}
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 */ }
}
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".