Modelo de Domínio

O modelo de domínio normalmente é uma tema tratado nas etapas técnicas de modelagem do software. Porém nele são abordados assuntos essencialmente do negócio, os quais podem ser antecipados antes de chegarem à etapas técnicas. O tema aprenseta como profissionais focados no negócio e times de desenvolvimento podem atuar junto antecipando essa questão, enriquecendo o entendimento de todos com relação ao domínio do software.

Modelo de domínio no desenvolvimento de software está associado a Domain-driven design (DDD), e de fato é a base deste conceito.

O DDD aborda visão de negócio e outros vários aspectos técnicos, que geralmente o torna um tema mais relevante para desenvolvedores(as). Porém uma figura importante no DDD é o Domain expert, o(a) especialista no domínino ou negócio, que normalmente não é desenvolvedor(a) mas é essencial para a construção do modelo de domínio a qual o software deverá atender.

Por este motivo, modelo de domínio está no pilar de negócio como um tema independente.

Domain Model

É recomendável que times de desenvolvimento e os especialistas no negócio atuem na construção do modelo já nos passos iniciais do projeto.

Os tópicos a seguir guiam a construção de um modelo de domínio inicial elencando alguns tópicos abordados no tema DDD, o qual é apresentado de forma completa no pilar de arquitetura.

Coração do software

“O coração do software está na sua capacidade de resolver problemas relacionados ao domínio para o seu usuário. Todas as outras características, por mais vitais que possam ser, se apoiam nessa finalidade básica. Quando o domínio é complexo, esta é uma tarefa difícil, exigindo a concentração de esforços de pessoas talentosas e capacitadas. Os desenvolvedores têm que mergulhar a fundo no domínio para adquirir conhecimentos sobre o negócio. É preciso afiar sua capacidade de modelagem e dominar o design de domínios.” por Eric Evans.

O livro Domain-Driven Design: Tackling Complexity in the Heart of Software, publicado em 2003 por Eric Evans, expõe a relevância de desenvolvedores(as) conhecerem o domínio do negócio. Um software só resolverá os problemas do cliente, se quem o construir conhecer o domínio do problema. Em alguns momentos isso soa repetitivo, e de fato é, já que pode definir se o software estará destinado ao sucesso ou condenado ao fracasso.

Pode-se considerar que o modelo de domínio é então um dos pontos mais relevantes na construção do software, pois se desenvolvedores(as) não se aprofundarem no domínio que irão atuar, o software poderá ser apenas um conjunto de linhas de código que entrega pouco valor.

Linguagem oblíqua (Ubiquitous Language)

A linguagem oblíqua refere-se ao uso de uma linguagem universal entre os envolvidos em um projeto. Todos, sem exceção, devem usar a mesma linguagem quando conversam sobre o negócio.

Essa linguagem engloba nomenclaturas e termos usados na composição de conceitos, contextos, entidades, funcionalidades e demais aspectos da solução.

Ao definirem uma linguagem oblíqua:

  • Profissionais na gestão e negócio devem usar em seus documentos, histórias, tarefas, etc.
  • Designers devem usar em seus protótipos e outros materiais.
  • Desenvolvedores(as) devem usar para nomear sistemas, subsistemas, componentes, classes, atributos, métodos, etc.
  • Times de Operação devem usar no monitoramento, alertas, etc.

Uma linguagem bem definida evita interpretações distintas sobre um mesmo termo ou conceito, assim como evita traduções mentais sobre termos. Abaixo segue um exemplo.

Um projeto fictício de nome Guia Hóspede, o qual está desenvolvendo uma solução para reservas de hotéis definiu como um dos segmentos de clientes sendo os: Viajantes (Hóspedes).

Esses termos surgiram nas conversas e definições iniciais no modelo de negócio e foram válidos para os primeiros passos. Com o andamento do projeto, foi necessário aprofundar o entendimento dos termos: Viajantes e Hóspedes.

Nos diálogos do time surgiram questões interessantes:
- Nem todos que reservam um quarto são viajantes!
- Hóspede é quem acessa o sistema, ou quem vai de fato usufruir da reserva?
- Podemos chamar o hóspede de usuário?
- Usuário é genérico demais, os hotéis terão usuários acessando como funcionários do hotel.

Nessa situação, algo que parecia claro no modelo de negócio, ao ser apresentado ao restante do time gerou várias interpretações.

Quando um projeto prossegue para etapas de execução sem a definição de uma linguagem universal, entregas podem ter um resultado diferente do esperado, partes do software podem precisar de constantes refatorações e o próprio cliente pode sofrer com mudanças inesperadas ou dificuldades no entendimento da solução.

A documentação da linguagem universal pode ser realizada através da criação de um glossário. Nele estará formalizado o entendimento dado a cada termo e conceito. O glossário deve ser acessível a todos integrantes dos times e sempre que necessário deve ser utilizado para realinhar as conversas.

Seguindo o exemplo do Guia Hóspede, o time criou um glossário inicial

  • Hotel: Cliente do Guia Hóspede, o qual disponibiliza na solução acomodações para hospedagem.
  • Hóspede: Pode ser um cliente do Guia Hóspede, estará associado a uma reserva de acomodações em um hotel.
  • Conta: Representação do cliente na solução, podendo ser um hóspede ou um hotel.
  • Usuário: Qualquer pessoa que acessa a solução Guia Hóspede. Um hóspede pode ser um usuário, um hotel pode ter vários usuários. Todo usuário está vinculado a uma conta.
  • Acomodação: Quarto ou área que o hotel disponibiliza para hospedagem.
  • Reserva: Ação de agendar a estadia em uma acomodação do hotel para um determinado período.
  • Outros termos e conceitos …

Dar nomes e definir conceitos não é uma tarefa simples, por vezes isso toma tempo dos times. É importante então não focar necessariamente na perfeição, mas em uma linguagem que todos compreendam e aceitem. Após essa definição é necessário ser rígido no uso da linguagem ao longo do tempo. Caso algum termo ou conceito precise mudar, é normal e faz parte do aprofundamento do domínio, devendo ser sempre comunicado.

Contexto delimitado (Bounded Context)

Uma solução normalmente abrange vários aspectos de um negócio e para auxiliar a compreensão e gestão, pode ser dividida em partes menores de acordo com tais aspectos. Essas partes menores são os contextos.

Cada contexto tem responsabilidades e limites bem definidos e também precisa considerar os pontos de integração ou dependências com outros contextos. Entidades da solução podem estar presentes em vários contextos, podendo ter características e responsabilidades diferentes em cada um. Entender essas características e responsabilidades é delimitar o contexto.

Bounded Context Exemplo de contextos delimitados. Fonte: Site de Martin Fowler

Ao delimitar as responsabilidades de entidades dentro de um contexto haverá o entendimento que algumas farão sentido em apenas um determinado contexto, já outras poderão pertencer a vários, porém a cada contexto provavelmente terão características e/ou até nomes diferentes, estando associadas normalmente por sua identificação. Na figura apresentada acima, as entidades Customer e Product aparecem em dois contextos diferentes, em cada contexto elas possuem suas próprias características. Isso se torna mais adequado do que por exemplo ter uma única entidade Customer que possua caracaterísticas relacionadas a dois contextos diferentes, pois isso extrapola os limites.

Seguindo o exemplo do Guia Hóspede, algumas entidades cuja limites foram analisados.

Conta

  • Todo cliente deverá ter uma conta. Hotéis são clientes e hóspedes podem ser clientes.
  • Hóspedes podem ou não ser clientes porque ao fazer uma reserva, o cliente que está acessando pode incluir na reserva outros hóspedes que não possuem acesso na solução, ou seja, não clientes.
  • Uma conta de hotel possui características específicas além das de uma conta normal.
  • Há então uma entidade Conta no contexto de Contas e uma entidade Conta no contexto de Hotéis, a qual estará associada a uma conta do contexto Contas e possuirá características adicionais.

Reserva

  • Uma reserva é realizada para um hotel, porém ela pertence ao contexto de Hóspedes já que eles são “os donos da reserva”. A reserva terá uma associação com hotel.

Polissemia

Polissemia refere-se a quando uma palavra ou expressão possui vários significados.

Em um exercício rápido:

  • Qual o significado da palavra Banco?
  • Pode ser banco para sentar ou uma agência bancária.
  • Na frase: A porta do banco travou. A mente associará a agência bancária.
  • Na frase: Chegando na praça, sente no banco e aguarde. A mente associará ao banco para sentar.

Nas duas frases o que determina o entendimento da palavra banco é o contexto. O que reforça a importância de dividir em contextos entidades e demais aspectos de um negócio.

Ainda há um outro cenário, novamente um exercício rápido:

  • Na frase: Estou esperando em frente ao banco da praça. Não há certeza sobre qual banco a frase refere-se.

Mesmo havendo a palavra praça que pode induzir a compreensão para banco de sentar, nada impede que exista uma agência bancária na praça, ou ao lado dela. Para evitar confusões de entendimento, ao ter uma polissemia busca-se escolher uma palavra mais adequada. A frase mais adequada poderia ser: Estou esperando em frente à agência bancária da praça.

Seguindo o exemplo do Guia Hóspede, alguns nomes modificados para facilitar entendimento:

  • Contexto Hóspedes: O contexto possui coisas relacionadas a hóspedes, mas na verdade ele agrupa entidades relacionadas a estadia do hóspede. Desta forma o termo Estadia representa melhor o contexto e não conflita com a entidade Hóspede.
  • Entidade Reserva: Os especialistas de negócio supõem que o Guia Hóspede poderá também atender a reservas de carros. Neste caso não será adequado ter entidades de mesmo nome que se refere a conceitos diferentes. Reservas de carro não é uma realidade ainda, não convém dedicar tempo para isso, porém é simples ser pró-ativo nessa questão entendendo que a reserva para hotel está associada a estadia de hóspedes, logo pode ganhar o nome de Reserva de Estadia.

Linguagem oblíqua + delimitação de contextos + atenção com polissemia, simplificam a tarefa de desenhar o modelo de domínio.

Desenho do modelo de domínio

Para desenhar o modelo de domínio a principal recomendação é: focar nos Contextos e Entidades.

Contexto já foi explorado nos tópicos acima, é uma parte menor do negócio que delimita um aspecto específico com a finalidade de organizar e facilitar a compreensão e gestão dos objetos que estão nele.

Entidades no modelo de domínios, não se refere a tabelas de um banco de dados. No modelo as entidades são a representação de um objeto relevante no negócio. Estar no modelo não significa que ela deverá ser persistida pela solução, caso venha a ser persistida, não indica a forma de persistência (relacional, não relacional, dentre outros).

Uma entidade pode representar:

  • Um objeto persistente na própria solução, podendo variar sua forma de persistência conforme necessidade, estratégias e tecnologias envolvidas.
  • Um objeto em memória, criado apenas em tempo de execução e trafegado na comunicação entre processos.
  • Um objeto persistente em uma solução terceira, onde o mesmo é recuperado e utilizado quando necessário.

É importante ter atenção ao que pode ser uma entidade e o que pode ser ações realizadas na solução. Em um contexto de pagamentos, por exemplo, a solução pode trabalhar com pagamentos agendados, isso não significa que deve haver uma entidade “Pagamento Agendado”. Pode-se ter a entidade Pagamento e a ação de “agendar pagamentos” criará um pagamento com estado agendado.

O detalhamento de ações e definições de persistência não devem ser trazidas no modelo de domínio inicial, elas ocorrem na etapa do pilar de arquitetura.

No modelo inicial, desenhar contextos e entidades tem a finalidade de apresentar e documentar a todos a composição do negócio.

Dicas para desenhar o modelo:

  • Pensar simples, criar um diagrama básico que organize entidades e contextos. Um diagrama UML de classes, por exemplo, não é a melhor abordagem nessa fase.
  • Usar ferramentas que facilitem o desenho, podendo ser editores online ou instalados no computador. Se não conhecer um bom editor, use um quadro branco, fotografe e compartilhe cada evolução, ao fim repasse o desenho para uma ferramenta.
  • Envolver as pessoas chaves para construção, mas com atenção para evitar reunir um número excessivo de pessoas a ponto de perder produtividade nas conversas.
  • Incluir no desenho:
    • Entidades, sendo elas o item inicial a ser considerado.
    • Associações entre entidades. Foque em sinalizar a associação, a cardinalidade pode ser detalhada depois.
    • Características(atributos) e exemplos das entidades, sendo opcionais quando contribuem para um melhor entendimento das entidades. Em fases seguintes os times irão dedicar maior atenção neste detalhamento.
    • Contextos, sendo eles o último a aparecer para organizar e delimitar as entidades. Ao incluir os contextos pode haver necessidade de novas entidades e isso é normal e parte do processo de construção do modelo.
  • Debater e ouvir todos que desejem se expressar, todas dúvidas e colocações são válidas, mesmo as que parecem “bobas”.
  • Chegar a um acordo durante debates. Nem sempre um consenso surge nas primeiras conversas, nesses casos chegue a um acordo para o momento e revisite a questão em uma próxima conversa.
  • Focar em fechar versões que já possibilitem os times iniciarem outros trabalhos de definição e implementação. A versão final e “perfeita” pode nunca chegar.

Seguindo o exemplo do Guia Hóspede, o modelo de domínio inicial.

Guia Hospede, Domain model Modelo criado com a ferramenta diagrams.net (draw.io), a qual possibilita o time acessar e navegar no diagrama através de um link compartilhado a todos.

Não foi utilizado uma notação formal, apenas setas indicando sentido e descrevendo a relação de forma textual, e isso é o suficiente já para que o time possa compreender.

Houve termos sem consenso, mas o time entrou em acordo e a linguagem utilizada tornou claro o domínio, possibilitando o time seguir os próximos passos. Os próximos passos podem também contribuir para mais clareza e possivelmente ajustes e evolução do modelo.

Com a versão inicial desenhada, algumas boas práticas:

  • Publicar para todo o time, preferencialmente um link acessível a todos.
  • Eleger “o dono do desenho”, ele deverá manter e comunicar atualizações no modelo.
  • Usar o modelo sempre que o time tiver dificuldades na compreensão do domínio.

Dicas relacionadas a desenhos e diagramas podem ser vistas no tema Documentação Técnica.

Aberto às mudanças

O modelo de domínio não é algo estático e definitivo. Ele evolui com o tempo e principalmente durante as implementações.

Mudanças nos conceitos de contextos, entidades e suas associações devem ser encarados como amadurecimento da compreensão do negócio. Ao ocorrer mudanças, provavelmente será necessário refatorar implementações e isso não deve ser encarado de forma negativa, pois se há uma visão mais adequada sobre o domínio, ela deve ser repassada ao código. Quanto mais demorar maior será o custo de refatoração, porém a pressa ao refatorar não pode impactar na cadência das entregas, por este motivo a refatoração deve ser planejada, estimada e executada junto às implementações do dia a dia.

Expansão do negócio gera normalmente as maiores mudanças, sendo assim é válido sempre antecipar no modelo as possibilidades previstas para o negócio. Talvez elas não sejam tratadas no momento, mas contribuem para o trabalho de construção de um modelo que absorva tais possibilidades adiante.

A capacidade de aceitar mudanças indica a possibilidade de melhorias, quando a necessidade de mudança é percebida mas ignorada, ela tende a continuar a ser necessária, porém cada vez com custo maior conforme o tempo passa.

Histórico