Ubiquitous Language

DDDomain-domain-driven design (DDD) não é um assunto novo (Eric Evans formalizou o conceito há mais de uma década). No entanto, é curioso como, até hoje, os conceitos básicos sobre o assunto despertam interesse, especialmente nas comunidades .NET. Ainda mais estranho é como esses mesmos conceitos são mal interpretados.

O fundamento do DDD reside no conceito da linguagem ubíqua. Não é na determinação do que é uma entidade, objeto de valor, agregado, serviço ou repositório.

A impressão que temos é que qualquer pessoa que começa a estudar DDD lê as primeiras páginas do livro Evans ou do livro Vernon e rapidamente pula diretamente para as páginas que descrevem os padrões.

Nós frequentemente falamos com pessoas de TI que pensam que ter uma linguagem ubíqua definida significa que o nome das classes e propriedades, escritas por programadores, está de acordo com o vocabulário dos especialistas do domínio. No entanto, isto é uma simplificação grosseira.

Para entender a importância da linguagem ubíqua, vamos começar com a “entidade” listada abaixo:

public class Employee{ public string Id { get; set; } public string Name { get; set; } public string Cpf { get; set; } public decimal Salary { get; set; }}

Aqui está um excelente exemplo de implementação anémica! Mas antes de continuar lendo, tente entender por que.

No nosso trabalho diário, quando usamos este exemplo, ouvimos sugestões de que falta comportamento nesta classe (O que é certo!). No entanto, quando perguntamos quais seriam esses “comportamentos”, descobrimos que as pessoas estão repetindo argumentos genéricos (de pessoas que também não “pegaram” a idéia) e não conseguem identificar o que está errado!

Um dos argumentos mais freqüentes é que os proprietários devem ser privados. Em seu lugar, deveríamos ter métodos “DefineXXX” que implementariam validações. Esta idéia não faz sentido porque o propósito dos setters é precisamente definir valores para as propriedades, e não haveria problema em implementar lógica de validação neles.

Os métodos de uma entidade devem explicitar as motivações para suas mudanças de estado. Além disso, deve haver pelo menos um construtor capaz de instanciar a entidade desde o início, em um estado válido.

Não é raro encontrar implementações de classes com propriedades que verificam, por exemplo, se o valor que você está tentando definir é não-nulo, mesmo quando essas mesmas propriedades têm valor nulo como valor padrão. Qual é a lógica aqui?

Veja outro exemplo de uma classe anêmica:

public class Customer { public string Name { get; private set; } public string Email { get; private set; } public DateTime BirthDate { get; private set; } public Customer(Guid id, string name, string email, DateTime birthDate) { Id = id; Name = name; Email = email; BirthDate = birthDate; } }

Na classe acima, temos um típico “record” para uma implementação funcional. Mas em uma linguagem orientada a objetos, isto não é uma entidade.

A idéia até faria sentido em uma linguagem puramente funcional onde a “entidade” está conceitualmente espalhada em várias funções que definem o comportamento, mas em C#, não faz sentido nenhum.

Vejamos uma segunda versão para a classe Employee:

public class Employee{ public string Id { get; private set; } public string Name { get; private set; } public string Cpf { get; private set; } public decimal Salary { get; private set; } public Employee(string name, string cpf) { //.. } public void RaiseSalary(decimal amount) { //.. }}

Esta vez a entidade é menos anêmica. Afinal de contas, as motivações que impulsionam a mudança de valor das propriedades são evidentes. Note como até mesmo o valor da escrita do teste torna-se mais explícito.

Anyway, ainda temos problemas. Nós nomeamos o método “RaiseSalary”, no entanto, esta não é a forma como os especialistas do domínio descrevem esta operação. A única maneira de definir razões reais para mudar os valores das propriedades é falando com esses experts.

Pensar sobre…

Identificar e implementar a linguagem ubíqua não é apenas para definir nomes de classes ou propriedades. A linguagem ubíqua deve ser revelada principalmente nas motivações para as mudanças de estado das nossas entidades explicitamente.

A compreensão da linguagem ubíqua é muito mais importante do que aprender os padrões. Sem o conhecimento real do domínio, o valor dos padrões de design é nulo.

Primeiro sobre aprender o mais importante. Tome o tempo e o esforço para compreender bem o domínio e soletrar a sua linguagem ubíqua. Depois pode até fazer sentido pensar em associar o DDD com conceitos técnicos mais avançados.

Deixe uma resposta

O seu endereço de email não será publicado.