Aluno: Fernando Alves Michalak – 211010503
Maximizando a Coesão
- Coesão é uma medida da diversidade dos "tópicos" abordados por uma entidade.
- Quanto menor a diversidade de assuntos abordados por uma entidade, maior a sua coesão.
- Uma entidade bem focada em um determinado aspecto do sistema, é uma entidade bem coesa.
- Sistemas onde os aspectos estão difusos são pouco flexíveis e dificultam extensões, modificações e reutilizações.
- Cada classe deve ser o mais coesa quanto possível.
- Cada classe deve representar apenas uma abstração.
- Classes não coesas podem trazer, pelo menos, 3 problemas:
- a classe é mais difícil de entender
- está se supondo que as duas (ou mais) abstrações representadas pela classe tem sempre uma relação de 1 p/ 1 entre si.
- pode ser necessário especializar a classe em várias dimensões baseadas nas várias abstrações
- Exemplo:
- Uma classe para uma conta bancária que inclui informações sobre o correntista (nome, endereço, etc.)
- Problema (2 acima): não permitirá contas conjuntas, se um correntista tem várias contas, os seus dados serão duplicados em cada conta o que gerará problemas de atualização e consistência.
- Probema (3): especialização na dimensão do tipo de conta (corrente, poupança) e no tipo de correntista (pessoa física ou jurídica).
- Solução: aumentar a coesão criando uma classe separada para o correntista
- Regrinhas simples para maximizar coesão:
- Outro exemplo:
- Representação de vôos e seus respectivos aeroportos
- Problema: se o vôo é repetido todos os dias, estaremos duplicando os objetos que representam o intinerário todos os dias.
- Isso ocorre pois estamos representando tando o intinerário quanto uma instância do vôo na mesma classe.
- Solução: separar as duas abstrações
- Flight Segment representa uma instância daquele vôo em um determinado dia, poderia incluir informações sobre a tripulação, por exemplo.
- Representação de vôos e seus respectivos aeroportos
- Os designs mais coesos descritos acima eliminam a redundância.
- Redundância desperdiça espaço e dificulta a atualização dos dados.
- Mas, muitas vezes, redundância pode melhorar o desempenho do sistema.
Minimizando o Acoplamento
- Acoplamento é
- O quão "amarrado" uma parte do sistema é às outras partes.
- O quão dependente uma parte do sistema é das estruturas internas das outras partes do sistema.
- Uma medida do quanto uma classe conhece do mundo à sua volta.
- Se uma classe A conhece (e depende) da interface de uma classe B, e a interface da classe B é modificada, a classe A terá que ser modificada também.
- Minimizando o acoplamento entre as classes (e objetos) de um sistema, nós facilitamos as modificações no sistema.
- Há várias formas de acoplamento, entre elas:
- Acoplamento de Identidade
- se um objeto guarda uma referência para outro, ele conhece a idêntidade do outro e, portanto, está acoplado a ele.
- reduz-se acoplamento de identidade eliminando associações no diagrama de classes e implementando associações de forma uni-direcional.
- note que em linguagens dinâmicas (Smalltalk, Self, Python, Lua) o acoplamento de identidade é mais leve do que em linguagens fortemente tipadas (Java, C++, C#)
- Acoplamento de Representação
- ocorre quando um objeto referencia outro, i.e., acessa o outro
- quanto mais específico o acesso (e.g., mexer nas variáveis públicas do outro objeto) maior o acoplamento.
- usando um método "acessor" diminui um pouco o acoplamento (pois o método esconde a implementação do dado).
- Acoplamento de Subclasses
- quando um objeto acessa uma subclasse usando a interface da subclasse ao invés de usar a interface da superclasse.
- um cliente deve sempre usar uma referência para o tipo mais geral possível.
- exemplo: em Java usar InputStream ao invés de usar FileInputStream.
- Uma regra fundamental relacionada a esta é que devemos sempre programar para as interfaces e nunca para a implementação .
- Assim, nos diagramas UML, as classes deveriam, sempre que possível, usar as <<interface>>s e não outras classes.
- Acoplamento de Herança
- Uma subclasse é acoplada à sua superclasse através de acoplamento de herança.
- É provavelmente o tipo de acoplamento mais forte.
- Se manifesta fortemente em tempo de compilação. Mas também em tempo de execução.
- O que uma classe herda em tempo de compilação não pode ser descartado em tempo de execução.
- Isso difere de agregação, quando um objeto pode se desfazer de seus agregados em tempo de execução.
- Exemplo: item de catálogo que é subclasse de item em estoque. E se a empresa decidir não guardar o item em estoque e encomendá-lo de terceiros toda vez que o item for encomendado?
Referência
Charles Richter. Designing Flexible Object-Oriented Systems with UML . Capítulo 4: Flexibility Guidelines for Class Diagrams. Macmillan Technical Publishing, 1999.
Nenhum comentário:
Postar um comentário