Diagramas de Classe e Princípios de Design OO
1. Introdução aos Diagramas de Classe
Os diagramas de classe são uma ferramenta central da UML para modelar a estrutura estática de um sistema, representando classes, os seus atributos, operações e relações.
- Finalidade:
- Descrever a organização do sistema em termos de abstrações e relacionamentos.
- Servir como base para a análise, design e implementação.
- Níveis de Modelação:
- Conceptual: Modelação abstrata de conceitos do domínio.
- Especificação: Definição de responsabilidades, interfaces (APIs) e operações.
- Implementação: Geração de código com detalhes concretos de classes e relações.
2. Representação de Classes em UML
- As classes têm até três compartimentos:
- Nome: Sempre em maiúsculas, representando uma abstração.
- Atributos: Características das instâncias da classe.
- Operações: Métodos ou serviços que podem ser solicitados às instâncias.
- Visibilidade:
+
Público: Acessível a todos.-
Privado: Restrito à própria classe.#
Protegido: Acessível a subclasses.- (Sem símbolo): Restrito ao pacote.
3. Relações Entre Classes
- Dependência:
- Uma classe depende de outra. Geralmente reflete um relacionamento temporário ou uso.
- Associação:
- Liga objetos de duas classes. Pode incluir navegação, multiplicidade e papéis.
- Reflexiva: Relaciona objetos da mesma classe (e.g., "Produto" composto de outros produtos).
- Agregação e Composição:
- Representam relações todo-parte.
- Agregação: Parte pode existir independentemente do todo.
- Composição: Parte depende completamente do todo para existir.
- Generalização/Especialização:
- Indica hierarquias de herança entre classes. Subclasses especializam a superclasse.
4. Declaração de Atributos e Operações
- Atributos:
- Sintaxe:
[visibilidade] nome : tipo [multiplicidade] {propriedades}
- Exemplo:
- nome: String [1..*] {frozen, ordered}
- Sintaxe:
- Operações:
- Sintaxe:
[visibilidade] nome([parâmetros]): tipoRetorno {propriedades}
- Exemplos:
+ getNome() : String {isQuery} # setAltura(out altura : double)
- Propriedades comuns incluem
abstract
,leaf
, eisQuery
.
- Sintaxe:
5. Princípios de Design Orientado a Objetos (SOLID)
Conjunto de boas práticas para criar sistemas modulares e de fácil manutenção:
- Single Responsibility Principle (SRP):
- Cada classe deve ter apenas uma razão para mudar.
- Benefícios: Facilita compreensão, manutenção e extensão.
- Open/Closed Principle (OCP):
- Classes devem ser abertas à extensão, mas fechadas para modificação.
- Exemplo: Adicionar novas funcionalidades por herança ou polimorfismo.
- Liskov Substitution Principle (LSP):
- Subtipos devem ser substituíveis pelos seus supertipos sem alterar o comportamento esperado.
- Interface Segregation Principle (ISP):
- Preferir interfaces específicas e menores a interfaces gerais.
- Vantagem: Reduz o acoplamento entre módulos.
- Dependency Inversion Principle (DIP):
- O código deve depender de abstrações (interfaces), e não de concretizações.
6. Mecanismos de Extensibilidade
- Estereótipos: Adicionam significado semântico a elementos do modelo (e.g.,
«interface»
,«create»
). - Valores Etiquetados: Permitem adicionar metadados.
- Exemplo:
{persistent, author="jfc"}
- Exemplo:
- Restrições: Impõem regras adicionais sobre o modelo.
- Exemplo:
{xor}
para relações mutuamente exclusivas.
- Exemplo:
7. Boas Práticas de Modelação
- KISS (Keep It Simple, Stupid): Manter modelos simples e diretos.
- DRY (Don’t Repeat Yourself): Evitar redundância para facilitar manutenção.
- SOC (Separation of Concerns): Cada classe com uma única responsabilidade clara.
- SLAP (Single Layer of Abstraction Principle): Operações devem manter o mesmo nível de abstração.