Criando Value-Objects e Entidades com Pydantic

Introdução

No design de software orientado a domínio (Domain-Driven Design, ou DDD), o conceito de Value-Objects e Entidades é essencial para criar um modelo de domínio claro e consistente. Value-Objects representam conceitos do domínio definidos por seus atributos, sem identidade própria, enquanto Entidades têm uma identidade única que as distingue, mesmo que seus atributos sejam iguais.

Value-Objects

Value-Objects são imutáveis e comparados por valor. Eles encapsulam conceitos do domínio que são essencialmente sem identidade, como uma data ou um endereço. Sua imutabilidade garante consistência e ajuda a evitar estados inválidos no sistema.

Entidades

As Entidades possuem uma identidade única e são comparadas por essa identidade, não pelos valores de seus atributos. Elas mantêm um ciclo de vida e podem ser modificadas durante esse ciclo.

O que é o Pydantic?

Pydantic é uma biblioteca Python que facilita a validação de dados e a criação de modelos fortemente tipados. Ele permite definir modelos que validam automaticamente os dados de entrada, garantindo que os dados do seu domínio estejam sempre em um estado válido.

Usando Pydantic para Criar Value-Objects e Entidades

Definindo um Value-Object com Pydantic

Vamos começar criando um Value-Object para representar um endereço. Usaremos o Pydantic para garantir que o endereço seja sempre válido.

from pydantic import BaseModel, Field, validator
from typing import Optional

class Endereco(BaseModel):
    rua: str = Field(..., min_length=1, description="Rua não pode ser vazia")
    cidade: str = Field(..., min_length=1, description="Cidade não pode ser vazia")
    estado: str = Field(..., min_length=2, max_length=2, description="Estado deve ter 2 caracteres")
    cep: str = Field(..., regex=r'^\d{5}-\d{3}$', description="CEP inválido")

    @validator('cep')
    def valida_cep(cls, v):
        if not v:
            raise ValueError('CEP inválido')
        return v

# Uso
endereco = Endereco(rua="Rua A", cidade="Cidade B", estado="CE", cep="12345-678")
print(endereco)

Definindo uma Entidade com Pydantic

Para definir uma Entidade, precisamos de um identificador único. Vamos criar uma Entidade Cliente que possui um identificador e outros atributos validados pelo Pydantic.

from pydantic import BaseModel, Field, EmailStr
from uuid import uuid4

class Cliente(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid4()), description="Identificador único do cliente")
    nome: str = Field(..., min_length=1, description="Nome não pode ser vazio")
    email: EmailStr
    idade: int = Field(..., ge=18, description="Idade mínima é 18 anos")

# Uso
cliente = Cliente(nome="João Silva", email="joao@example.com", idade=30)
print(cliente)

Conclusão

A utilização do Pydantic para definir e validar Value-Objects e Entidades em um contexto de DDD garante a integridade dos dados e ajuda a manter um modelo de domínio claro e consistente. Value-Objects e Entidades bem definidos promovem um design de software mais robusto e fácil de manter. Experimente aplicar essas técnicas no seu próximo projeto e veja como elas podem transformar a forma como você lida com a validação de dados.

Comentários

Postagens mais visitadas deste blog

Um caso de uso não deve depender de outro caso de uso

O que são Aggregates?

Repositórios não devem ser disponibilizado para os clientes