MAC 441/5714 - Programação Orientada a Objetos
Aula 13 - 28/4/2005
Aumentando a Flexibilidade (continuação)
Generalização de Classes
- Uma superclasse é introduzida por um de dois motivos:
- duas ou mais classes tem implementação em comum
- duas ou mais classes tem uma interface em comum


Especialização de Classes
- uma classe pode especializar outra de 4 formas:
- adicionando estado na forma de um atributo
- adicionando estado na forma de uma associação
- adicionando comportamento na forma de um método
- alterando comportamento com um novo método que se
sobrepõe a um método da superclasse
- adicionando essas coisas na superclasse poderia torná-la
inchada,
não coesa. Então, criamos a subclasse para garantir a
coesão
da arquitetura.
Evite Distinção de Classes Baseada no Estado (p/
melhorar
a flexibilidade)
- Se a única diferença entre uma classe e sua
sub-classe
é o valor de algum atributo (estado), podemos ter problemas.
- Exemplo: na FIGURA
4.21 um
empregado pode se tornar gerente e depois
deixar de se tornar gerente.
- O tipo do objeto muda ao longo do tempo, portanto é
necessário
criar um novo objeto, destruir o antigo e atualizar todas as
referências
para ele.
- A solução usando herança da FIGURA
4.22 não
resolve o problema.
- O problema é melhor resolvido usando
agregação.
- FIGURA
4.23.
Evite Superclasses Concretas (p/ melhorar a flexibilidade)
- Comparando as figuras
4.21 e
4.22, vemos que
- a primeira é mais simples (o que é bom)
- mas a segunda é mais flexível
- No design da figura
4.21,
todas as
propriedades de um empregado estão
obrigatoriamente no gerente.
- No design da figura
4.22
podemos
ter propriedades específicas
de empregados não-gerentes (exemplo chato: cartão de
ponto).
Especialização vs. Agregação
- Ou seja, herança versus delegação (ambas
são
utilizadas para acrescentar coisas novas a uma classe).
- Evite especializações nas dimensões erradas
- especializações em múltiplas
dimensões
geram um crescimento exponencial no número de classes.
- vimos isso no exemplo das figuras
4.1
e
4.2
- isso gera uma herança múltipla em forma de
losango
que gera muita confusão.
- Colocação das propriedades na classe correta
(dentro
de uma hierarquia)
- propriedades de uma classe devem fazer sentido em todas as
subclasses.
- propriedades comuns a várias subclasses devem ser
definidas
na superclasse
- Com isso, vamos jogando as definições das
propriedades
para cima e para baixo até achar o ponto certo.
- Cuidado ao usar herança múltipla
- em algumas empresas é proibido
- em algumas linguagens não é possível
- permite a possibilidade que uma classe herde
implementações
conflitantes de métodos
- muitas vezes, usar herança múltipla é um
erro
conceitual pois especialização é uma
relação
do tipo "é um tipo de".
- (mau) Exemplo: FIGURA
4.32.
Agregação
- Como tornar arquiteturas construídas com
agregação
mais flexíveis
- esconda as partes internas do agregado
- Limite o que uma classe conhece sobre a outra.
- No exemplo da figura
4.33,
os
clientes do caixa automático
não deveriam acessar diretamente as classes agregadas.
- O padrão Façade pode ajudar aqui.
- reutilização das partes agregadas.
- se eu quiser usar a classe leitora de cartões tanto
num
caixa automático quanto numa máquina de pedágio.
- quando o cartão é inserido e lido, o leitor
precisa
enviar uma mensagem para o caixa automático ou para a
máquina
de pedágio.
- se no design original há uma associação
entre
o leitor de cartão e um caixa automático, o design
precisa
ser alterado pois a máquina de pedágio não
é
do tipo caixa automático.
- para introduzir a flexibilidade, é necessário
eliminar
o acoplamento do leitor de cartão com o caixa.
- Solução: criar superclasse abstrata "card
driven"
comum a todos os tipos de coisas que utilizarão o leitor de
cartões.
- Figure
4.34.
Referência
Charles Richter. Designing Flexible Object-Oriented Systems with UML
. Capítulo 4: Flexibility Guidelines for Class Diagrams.
Macmillan
Technical Publishing, 1999.
Próxima Aula
Aula
Anterior
Página de MAC 413/5715
Página do Fabio
Página do DCC