57
O Padrão Decorator
3 O Pado Decorator
Chame este capítulo de “Olho de design para o garoto
da herança”. Examinaremos novamente o típico uso
excessivo da herança e você aprenderá a decorar suas
classes no tempo de execução usando uma forma
de composição de objeto. Por quê? Depois que você
descobrir as técnicas de decoração, poderá dar novas
responsabilidades a seus objetos (ou de outra pessoa)
sem fazer nenhuma mudança de código nas classes
básicas.
Decorando objetos
Eu achava que os homens de
verdade colocavam tudo em
subclasses. Até conhecer o
poder da extensão no tempo de
execução, no lugar de no tempo de
compilação. Agora olhe para mim!
CG_ucpadroes_RI2016.indb 57 22/11/2016 09:36:12
58
Use a Cabeça Padrões de Projetos
Bem-vindo ao Starbuzz Coffee
O Starbuzz Coee (empresa como uma lanchonete) ficou conhecido como o café com o
crescimento mais rápido da região. Se você já viu um na sua esquina, olhe para o outro lado
da rua: você verá outro.
Como eles cresceram muito rápido, estão tendo dificuldades em atualizar seus sistemas de
pedidos para corresponder a suas ofertas de bebidas.
Quando eles entraram no negócio, projetaram suas classes assim...
Além do seu café, você também pode pedir vários condimentos, como leite com espuma, soja
e moca (também conhecido como chocolate), misturados com leite batido. Como o Starbuzz co-
bra um valor por cada condimento, eles realmente precisam incluí-los nos sistema de pedido.
Esta é a primeira tentativa...
//Outros métodos úteis...
//Outros métodos úteis...
Beverage (bebida) é uma classe
abstrata, subclassificada por todas
as bebidas oferecidas no café.
O método cost()
é abstrato; as
subclasses precisam
definir sua própria
implementação.
A variável de instância de descrição
é definida em cada subclasse e
conm uma descrição da bebida,
como “O melhor café torrado.
O método getDescription() retorna
a descrição.
Cada subclasse implementa cost() para retornar o custo da bebida.
Uau! Você pode dizer
“explosão de classe”?
Cada método de custo calcula
o custo do café juntamente
com outros condimentos no
pedido.
CG_ucpadroes_RI2016.indb 58 22/11/2016 09:36:13
59
O Padrão Decorator
Bem, vamos tentar. Vamos começar com a classe básica Beverage e adicionar variáveis de
instância para representar se cada bebida tem ou não leite, soja, moca e creme...
Agora, vamos adicionar as subclasses, uma para cada bebida do menu:
Poder
da Mente
É óbvio que o Starbuzz criou um pesadelo de manutenção para eles mesmos.
O que acontece quando o preço do leite sobe? O que eles fazem quando
adicionam uma nova cobertura de caramelo?
Pensando além do problema de manutenção, qual dos princípios de projeto
que eles estão violando?
Agora, vamos implementar cost() em
Beverage (em vez de mantê-lo abstrato)
para que ele possa calcular os custos
associados com os condimentos para uma
determinada instância de bebida. As
subclasses ainda irão substituir cost(), mas
também irão invocar a superversão para
poder calcular o custo total da bebida
básica mais os custos dos condimentos
adicionados.
//Outros métodos úteis...
Estes obtêm e definem os valores
boleanos para os condimentos.
Novos valores boleanos para cada
condimento.
Isso é estúpido! Por que precisamos
de todas essas classes? Não podemos
usar apenas variáveis de instância e
herança na superclasse para monitorar os
condimentos?
Dica: estão violando totalmente dois deles!
CG_ucpadroes_RI2016.indb 59 22/11/2016 09:36:13
60
Use a Cabeça Padrões de Projetos
// Outros métodos úteis...
A superclasse cost() irá calcular os
custos de todos os condimentos,
enquanto a cost() substituída
nas subclasses irá estender essa
funcionalidade para incluir custos que
especificam o tipo da bebida.
Cada método cost() precisa
computar o custo da bebida e depois
adicionar os condimentos chamando
a implementação da superclasse de
cost().
Escreva os métodos cost() para as seguintes classes (pseudo-Java está OK):
public class Beverage {
public double cost() {
}
}
public class DarkRoast extends Beverage
{
public DarkRoast() {
description = “Most Excellent Dark
Roast”;
}
public double cost() {
}
}
Aponte seu lápis
CG_ucpadroes_RI2016.indb 60 22/11/2016 09:36:13
61
O Padrão Decorator
Certo, um total de
cinco classes. Esse
é denitivamente o
caminho
Não tenho certeza. Posso ver
alguns possíveis problemas com
essa abordagem pensando em como
o design poderia precisar mudar no
futuro.
Aponte seu lápis
Quais requisitos ou outros fatores poderiam mudar e afetar esse projeto?
Mudanças de preços dos condimentos irão nos forçar a alterar o código existente.
Novos condimentos irão nos forçar a adicionar novos métodos e alterar o método de custo na superclasse.
Agora podemos ter novas bebidas. Para algumas dessas bebidas (chá gelado?), os condimentos podem não
ser apropriados, mas a subclasse Tea (chá) ainda irá herdar os métodos como hasWhip().
E se um cliente quiser um moca duplo?
Sua vez:
Conforme vimos
no Capítulo 1,
esta é uma
péssima idéia!
CG_ucpadroes_RI2016.indb 61 22/11/2016 09:36:13

Get Use A Cabeça Padrões E Projetos now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.