🏛️ CAPÍTULO 12: DIAGRAMA DE CLASSES (CONCEITOS)
🎯 1. Objetivos de Aprendizagem & Competências
Estimativa de Dedicação: 2 horas de estudo autoguiado.
Ao final deste capítulo, você será capaz de:
- 🔹 Compreender a estrutura do Diagrama de Classes da UML como pilar fundamental da modelagem estática e da Programação Orientada a Objetos (POO).
- 🔹 Dominar a representação dos três compartimentos canônicos: Nome da Classe, Atributos Tipados e Métodos com Assinaturas de Retorno.
- 🔹 Aplicar os modificadores de visibilidade da UML: Público (
+), Privado (-), Protegido (#) e Pacote (~). - 🔹 Mapear classes UML para código Python 3.11+ utilizando propriedades protegidas (
@property) e modelos do SQLAlchemy 2.0.
🏢 2. Cenário Corporativo & Estudo de Caso (TecProExpress)
Na TecProExpress, a equipe financeira identificou um bug crítico: funções espalhadas pelo sistema alteravam diretamente a variável saldo de motoristas parceiros sem registrar o log de auditoria e sem validar se o valor ficaria negativo.
O Desafio: Como Arquiteto de Software, você deve redesenhar o domínio aplicando o princípio do Encapsulamento. A classe
CarteiraDigitaldeve manter o saldo estritamente privado (-), expondo apenas métodos públicos de depósito e saque com validação defensiva de integridade.
🧠 3. Fundamentação Teórica & Modelos Visuais
3.1. Anatomia da Classe na UML 2.5
Uma classe é representada na UML por um retângulo com três compartimentos horizontais:
classDiagram
class CarteiraDigital {
-String idCarteira
-Decimal saldoPrivado
#String idTitular
+depositar(Decimal valor) bool
+sacar(Decimal valor) bool
+consultarSaldo() Decimal
}
3.2. Modificadores de Visibilidade e Encapsulamento
| Símbolo UML | Visibilidade | Semântica de Engenharia | Equivalente em Python 3.11+ |
|---|---|---|---|
+ | Público (Public) | Acessível por qualquer classe ou módulo da aplicação. | def consultar_saldo(self): |
- | Privado (Private) | Acessível única e exclusivamente por métodos da própria classe. | self.__saldo = saldo (Name Mangling) |
# | Protegido (Protected) | Acessível pela própria classe e por suas subclasses derivadas. | self._titular = titular (Convenção) |
~ | Pacote (Package) | Acessível por classes pertencentes ao mesmo pacote/módulo. | Módulos internos (_internal.py) |
💻 4. Aplicação Prática & Código Executável (Python 3.11+)
📋 Pré-requisitos e Instalação
Este exemplo utiliza exclusivamente módulos da biblioteca padrão do Python (decimal), não necessitando de bibliotecas de terceiros:
python --version # Requer Python 3.11 ou superior
💻 Código Completo e Autocontido (carteira_digital.py)
Transposição da classe modelada na UML para código Python com encapsulamento defensivo e validações de invariantes de negócio:
"""
Módulo: carteira_digital.py
Domínio: Encapsulamento e proteção de saldo financeiro.
"""
from decimal import Decimal
class CarteiraDigital:
def __init__(self, id_carteira: str, titular: str, saldo_inicial: Decimal = Decimal("0.00")):
self.id_carteira: str = id_carteira # + Público
self._titular: str = titular # # Protegido
self.__saldo: Decimal = saldo_inicial # - Privado
def depositar(self, valor: Decimal) -> bool:
"""+ Método Público para entrada de recursos com validação."""
if valor <= Decimal("0.00"):
raise ValueError("O valor de depósito deve ser estritamente positivo.")
self.__saldo += valor
return True
def sacar(self, valor: Decimal) -> bool:
"""+ Método Público com trava de saldo insuficiente."""
if valor <= Decimal("0.00"):
raise ValueError("Valor de saque inválido.")
if valor > self.__saldo:
raise PermissionError("❌ Saldo insuficiente na carteira.")
self.__saldo -= valor
return True
@property
def saldo(self) -> Decimal:
"""+ Getter público controlado."""
return self.__saldo
if __name__ == "__main__":
print("--- Teste de Encapsulamento da Carteira Digital ---")
carteira = CarteiraDigital("CRT-2026-99", "Marcos Silva", Decimal("500.00"))
carteira.depositar(Decimal("250.00"))
carteira.sacar(Decimal("100.00"))
print(f"Titular: {carteira._titular}")
print(f"✅ Saldo da Carteira {carteira.id_carteira}: R$ {carteira.saldo:.2f}")
# Teste de violação de regra de negócio
try:
carteira.sacar(Decimal("1000.00"))
except PermissionError as e:
print(f"Validação defensiva disparada: {e}")
🚀 Como Executar
Execute o script diretamente no terminal:
python carteira_digital.py
🖥️ Saída Esperada no Terminal
--- Teste de Encapsulamento da Carteira Digital ---
Titular: Marcos Silva
✅ Saldo da Carteira CRT-2026-99: R$ 650.00
Validação defensiva disparada: ❌ Saldo insuficiente na carteira.
💡 5. Checkpoint de Engenharia & Boas Práticas
- Encapsulamento é Segurança: Nunca deixe atributos críticos (preço, saldo, estoque) acessíveis diretamente de fora da classe. Use métodos de negócio (
adicionar_item(),processar_baixa()) para garantir que as regras e invariantes sejam sempre validadas. - Anti-Pattern Anemic Domain Model: Evite criar classes que são apenas "sacos de getters e setters" sem qualquer lógica de negócio, espalhando cálculos e regras em funções utilitárias desordenadas.
🔗 6. Conexão com os Projetos Integradores
| Projeto Integrador | Como o conceito deste capítulo é aplicado no PI |
|---|---|
| PI-03: PDVLite | Classe Venda com encapsulamento do cálculo do total de itens e aplicação de desconto fiscal. |
| PI-09: FinLite | Classe ContaBancaria protegendo o saldo contábil contra baixas não autorizadas. |
🧪 7. Quiz de Fixação e Autoavaliação (Formative Assessment)
🧪 Quiz de Autoavaliação — Capítulo 12
🧪 Quiz de Autoavaliação — Capítulo 12
1. No diagrama de classes da UML, qual símbolo gráfico representa que um atributo possui visibilidade 'Privada' (Private)?
-
A)
+(Mais) -
B)
-(Menos) -
C)
#(Cerquilha/Hash) -
D)
~(Til)
💡 Ver Resposta e Justificativa
Resposta Correta: B
Justificativa: O símbolo - representa visibilidade Privada (Private), garantindo que apenas métodos internos da própria classe possam acessar e modificar o atributo.
2. O que caracteriza o princípio da Orientação a Objetos conhecido como 'Encapsulamento'?
- A) Permitir que qualquer script altere variáveis globais sem restrições.
- B) Ocultar os detalhes internos de implementação e proteger o estado do objeto, permitindo acesso apenas através de uma interface pública validada.
- C) Transformar todo o banco de dados em arquivos CSV.
- D) Executar múltiplos programas na mesma máquina virtual.
💡 Ver Resposta e Justificativa
Resposta Correta: B
Justificativa: O encapsulamento blinda o estado interno do objeto contra manipulações externas indevidas, mantendo a integridade e coesão das regras de negócio.
3. Na representação de um método na UML + calcularTotal(desconto: Decimal): Decimal, o tipo após os dois pontos no final indica:
- A) O nome da tabela do banco de dados.
- B) O tipo de dado do primeiro parâmetro.
- C) O tipo de dado do valor de retorno do método.
- D) A versão do compilador.
💡 Ver Resposta e Justificativa
Resposta Correta: C
Justificativa: Na sintaxe da UML, o tipo após os dois pontos da assinatura do método especifica o tipo de retorno retornado pela função.
🛠️ 8. Ponte para a Ação: Laboratório Prático
Coloque esta teoria em prática executando o roteiro de laboratório autoguiado:
👉 ATIVIDADE 07: DIAGRAMA DE CLASSES (UML)
📌 9. Resumo Executivo & Key Takeaways
- Planta Estática: O Diagrama de Classes define a estrutura de dados e as operações fundamentais do sistema.
- 3 Compartimentos: Nome da Classe, Atributos Tipados e Métodos com assinaturas.
- Encapsulamento Estrito: Atributos devem ser privados (
-) ou protegidos (#); métodos de negócio compõem a interface pública (+). - Mapeamento ORM: Classes UML conectam-se diretamente às tabelas relacionais do SQLAlchemy e schemas do Pydantic.