Diagrama de Classes - UML

Diagrama de Classes

O diagrama de classes é um dos diagramas mais importantes da UML, utilizado para representar a estrutura estática de um sistema, mostrando as classes, seus atributos, métodos e os relacionamentos entre elas. Ele é essencial para modelar a lógica do sistema e facilitar a comunicação entre desenvolvedores.

O que é um Diagrama de Classes?

O diagrama de classes permite visualizar as classes que compõem o sistema, seus atributos e métodos, além de como essas classes se relacionam entre si. Ele é usado para definir a estrutura lógica do sistema antes da implementação.

  • Classes: Representam os objetos do sistema, contendo atributos (dados) e métodos (comportamentos).
  • Atributos: Características das classes, como nome, idade, etc.
  • Métodos: Ações que as classes podem realizar, como calcularSaldo().

Atributos e Métodos

Os atributos e métodos de uma classe podem ter diferentes visibilidades, que definem seu acesso:

  • Público (+): Acessível por qualquer classe.
  • Privado (-): Acessível apenas dentro da própria classe.
  • Protegido (#): Acessível dentro da classe e por suas subclasses.
class ContaComum {
    -numeroConta: long
    -saldoConta: double
    +depositar(valor: double): void
    +sacar(valor: double): boolean
  }

Relacionamentos entre Classes

As classes podem se relacionar de várias formas, cada uma representando um tipo de interação:

  • Associação: Relacionamento simples entre classes (ex: Pessoa possui Conta).
  • Agregação: Relação "todo-parte" onde a parte pode existir sem o todo (ex: Departamento contém Funcionários).
  • Composição: Relação "todo-parte" mais forte, onde a parte não existe sem o todo (ex: Casa contém Quartos).
  • Herança (Generalização/Especialização): Relação onde uma classe filha herda atributos e métodos da classe pai (ex: ContaEspecial herda de ContaComum).
"Os relacionamentos definem como as classes colaboram entre si, refletindo as regras de negócio do sistema."

Multiplicidade

A multiplicidade define quantos objetos de uma classe podem se relacionar com objetos de outra classe:

  • 1..1: Um para um (ex: um Funcionário tem um CPF).
  • 1..*: Um para muitos (ex: um Departamento tem vários Funcionários).
  • *: Muitos para muitos (ex: um Aluno pode se matricular em vários Cursos).
class Pessoa {
    -nome: String
    -contas: Conta[0..*]  // Uma pessoa pode ter zero ou mais contas
  }

Exemplo Prático: Sistema Bancário

Em um sistema bancário, podemos modelar classes como Conta, Cliente e Transação:

class Cliente {
    -nome: String
    -cpf: String
    +adicionarConta(conta: Conta): void
  }

  class Conta {
    -numero: String
    -saldo: double
    +depositar(valor: double): void
    +sacar(valor: double): boolean
  }

  class Transacao {
    -valor: double
    -data: Date
    +executar(): void
  }

Relacionamentos: Um Cliente pode ter várias Contas, e uma Conta pode ter várias Transações.

Classes Abstratas e Interfaces

Classes abstratas e interfaces são usadas para definir comportamentos comuns:

  • Classe Abstrata: Não pode ser instanciada, serve como base para outras classes (ex: Animal).
  • Interface: Define um contrato que as classes devem implementar (ex: Autenticavel com método autenticar()).
abstract class Animal {
    -nome: String
    +emitirSom(): void
  }

  interface Autenticavel {
    +autenticar(senha: String): boolean
  }

Restrições e Estereótipos

Restrições e estereótipos adicionam detalhes ao diagrama:

  • Restrições: Regras que devem ser seguidas (ex: {saldo >= 0}).
  • Estereótipos: Marcam classes com papéis específicos, como <<entity>> ou <<service>>.
class Conta {
    -saldo: double {saldo >= 0}
  }

  <<entity>>
  class Cliente {
    -nome: String
  }