Modelação Arquitetural

Desenvolvimento de Sistemas de Software

By Pedro Pereira23-10-2024

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:
    1. Conceptual: Modelação abstrata de conceitos do domínio.
    2. Especificação: Definição de responsabilidades, interfaces (APIs) e operações.
    3. 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:
    1. Nome: Sempre em maiúsculas, representando uma abstração.
    2. Atributos: Características das instâncias da classe.
    3. 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

  1. Dependência:
    • Uma classe depende de outra. Geralmente reflete um relacionamento temporário ou uso.
  2. 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).
  3. 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.
  4. 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}
      
  • Operações:
    • Sintaxe: [visibilidade] nome([parâmetros]): tipoRetorno {propriedades}
    • Exemplos:
      + getNome() : String {isQuery}  
      # setAltura(out altura : double)  
      
    • Propriedades comuns incluem abstract, leaf, e isQuery.

5. Princípios de Design Orientado a Objetos (SOLID)

Conjunto de boas práticas para criar sistemas modulares e de fácil manutenção:

  1. Single Responsibility Principle (SRP):
    • Cada classe deve ter apenas uma razão para mudar.
    • Benefícios: Facilita compreensão, manutenção e extensão.
  2. Open/Closed Principle (OCP):
    • Classes devem ser abertas à extensão, mas fechadas para modificação.
    • Exemplo: Adicionar novas funcionalidades por herança ou polimorfismo.
  3. Liskov Substitution Principle (LSP):
    • Subtipos devem ser substituíveis pelos seus supertipos sem alterar o comportamento esperado.
  4. Interface Segregation Principle (ISP):
    • Preferir interfaces específicas e menores a interfaces gerais.
    • Vantagem: Reduz o acoplamento entre módulos.
  5. 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"}
  • Restrições: Impõem regras adicionais sobre o modelo.
    • Exemplo: {xor} para relações mutuamente exclusivas.

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.

Apresentação de conteúdos concisos.