Oi Habr.Hoje fui ao canal #school na GoCommunity em russo
no Slack e encontrei
um diálogo interessante lá . Esse diálogo me levou a refletir sobre como meus colegas interpretam o conceito de
"modelo de domínio" .
Como se viu, existem muitas interpretações incorretas ou pouco precisas e, às vezes, completamente imprecisas desse termo, o que essencialmente o distorce. Em torno desse diálogo, nasceu a ideia deste artigo. Detalhes sob o corte.
Pergunta sobre arquitetura.
Portanto, o desenvolvedor fez a seguinte pergunta na comunidade:
Diga-me como fazer a arquitetura corretamente, digamos que fiz um tablet no banco de dados, pedi reformas para gerar um modelo para mim, posso usar esse modelo como modelo de domínio no meu aplicativo ou é melhor criar meu próprio modelo de domínio e fazer um adaptador que me fornecerá exatamente o meu modelo de domínio criando a partir de um modelo de reforma? ”
Para qual outro programador deu a seguinte resposta:
O mais simples é a arquitetura com um modelo anêmico. é quando o modelo de banco de dados = modelo de domínio = modelo de resposta da API. O modelo de domínio rico é um animal raro e geralmente degenera em anemia. Por anêmica, entende-se uma estrutura de DTO. o conjunto usual de atributos (campos) sem métodos. A lógica degenera em um conjunto de funções que operam nesse dto. Fowler às vezes considera essa arquitetura antipadrão. Mas então uma boa solução de microsserviço, etc.
Depois de ler isso, repentinamente percebi por que há tanta controvérsia em torno da organização da camada de lógica de negócios e por que muitas pessoas deixam de colocar em prática abordagens como
Arquitetura Limpa etc. O que significa
“arquitetura com um modelo anêmico” ?
Se você tentar encontrar esse conceito na rede, provavelmente não o encontrará, porque não existe essa arquitetura. Existe o conceito de
“AnemicDomainModel” e, se voltarmos para o mesmo Fowler, verifica-se que essa é apenas uma
abordagem processual para criar uma arquitetura de aplicativo (Olá Fortran, ALGOL, COBOL, BASIC, Pascal e C). Em essência, é isso que o autor da resposta chama de
“arquitetura com um modelo anêmico” .
O modelo de domínio
A seguir, surge a próxima pergunta: o
“modelo anêmico” é essencialmente um modelo? Eu acho que não, e é por isso.
A verdade é que o modelo de domínio não é um modelo de dados, ao contrário do
"modelo de banco de dados" ou
"modelo de resposta da API" . O modelo de domínio
tem uma definição muito específica . Além disso, é errado interferir no modelo de banco de dados, que é essencialmente um
modelo de dados .
Quando se trata do modelo de domínio, esse é precisamente o modelo conceitual. E essa é a totalidade dos conceitos da área de assunto e as relações entre eles (ou seja, a totalidade do comportamento e dos dados). Em geral, o principal recurso que distingue um modelo de uma área de assunto de outro é precisamente um conjunto de regras de negócios.
Sim, o modelo conceitual pode trabalhar com dados que são apresentados em diferentes formas (dados do banco de dados ou respostas da API), mas a essência disso não muda, o
comportamento é primordial . Passamos a entrada para o modelo para obter uma saída específica. Esse resultado é alcançado implementando a lógica de negócios dentro do modelo (em outras palavras, aplicando regras de negócios). Encontro aqui uma analogia com modelos matemáticos e modelagem de processos tecnológicos (Olá, anos de estudante).
O que é repleto de substituição de conceitos?
Quando você chama as estruturas de dados de
"modelo de domínio" , você é livre ou não para substituir conceitos. Isso leva ao fato de que muitas vezes a lógica de negócios se espalha por todo o aplicativo. De fato, o modelo da área de assunto, nesse caso, é o conjunto muito difuso de funções que opera com estruturas de dados.
No caso de desenvolver aplicativos de médio e grande porte, um mal-entendido ou mistura desses conceitos, via de regra, leva a vários problemas e perguntas já no início do desenvolvimento do sistema, sem mencionar o suporte a longo prazo. Entre eles, por exemplo, existem perguntas comuns como:
- "- Onde validar os dados?"
- "- Como evitar dependências cíclicas?"
- "- Essa é a lógica de negócios em geral?"
- "- E onde mantemos a lógica de negócios?"
- etc.
Além disso, se você tiver um CRUD simples, ou seja, essencialmente uma interface para o banco de dados, provavelmente não haverá problemas. Se você estiver gravando uma biblioteca no nível da infraestrutura (por exemplo, para trabalhar com uma rede ou com o mesmo banco de dados), também não haverá problemas. Isso ocorre porque existe uma RFC e todas as “regras de negócios” estão claras há muito tempo e a lógica há muito tempo. Você pode escrever um programa processual simples, e tudo ficará bem de qualquer maneira.
Se voltarmos ao fato de que o diálogo sobre modelos de domínio surgiu na comunidade Go, eu diria que sim. Como o Go é uma linguagem multiparadigma e suporta vários dos conceitos de OOP mais bem-sucedidos (Composition, Interfaces), não os ignore ao modelar um domínio e escrever código exclusivamente em um estilo procedural, como se você estivesse trabalhando com BASIC ou C.
Ao interpretar corretamente o conceito de "modelo de domínio", torna-se bastante óbvio o motivo pelo qual é habitual separar a lógica de negócios em uma camada separada. Também fica claro como você pode selecionar essa mesma camada e implementar a Arquitetura Limpa ou qualquer outra variação dela. Ao isolar uma camada separada, criamos essencialmente uma biblioteca que implementa o modelo conceitual na forma de código de programa. Como resultado, a lógica de negócios fica encapsulada na estrutura desta biblioteca e não se espalha por todo o aplicativo (como em uma abordagem processual pura).
Obviamente, entender esses conceitos não o salvará de erros de design, não o tornará um desenvolvedor ou arquiteto de sistemas ideal e não o ensinará a fazer tudo certo da primeira vez. Aqui, não apenas a teoria é importante, mas também a prática. No entanto, assim que você entender corretamente os conceitos e interpretar as definições, muitas coisas se tornarão muito mais óbvias e simples para você.
Para resumir.
- Não é correto chamar "dados" de modelo de domínio.
- Um modelo de domínio é um modelo conceitual que inclui comportamento e dados. Ele pode ser encapsulado em uma camada separada ou pode ser espalhado por todo o aplicativo.
- “Arquitetura com um modelo anêmico” nada mais é do que uma abordagem processual para criar uma arquitetura de aplicativo na qual o modelo de domínio está espalhado por todo o aplicativo
Preste atenção às definições, estude-as mais profundamente do que apenas lendo na diagonal. Muitas vezes somos preguiçosos e pegamos informações em pedaços, após o que certamente ocorre distorção. Não se esqueça de voltar e pegar coisas que lhe parecem óbvias por um longo tempo, e sempre consulte as fontes e chame uma pá de pá.
Bom para todos! Obrigado pela atenção.
PS. Ficarei feliz em ouvir críticas construtivas, bem como sua visão do que é um "modelo de domínio". Referências à fonte são bem-vindas.
UPD: O artigo não é uma tentativa de interpretar livremente o conceito de "modelo de domínio" e de colocar nesse conceito um significado que eu conheço. Quero transmitir isso: O significado desse conceito já foi investido há muito tempo e é descrito em detalhes em livros e artigos sobre ComputerScience. O artigo é uma tentativa de transmitir aos colegas a importância da percepção correta desses mesmos conceitos, sem distorcer seu significado (isso é importante porque, na prática, permitirá que você escreva um código mais significativo).
UPD2: Eu não sou um arquiteto teórico empresarial. Eu sou o mesmo desenvolvedor praticante que você. Eu escrevo código todos os dias e falo sobre essas coisas para melhorar meu código e os clientes mais felizes. Se, na sua opinião, distorci o significado original, compartilhei links para a fonte e indique onde o coloquei incorretamente, para que eu possa corrigi-lo.
UPD3: Porque muitos interpretam o termo “área de assunto” de diferentes maneiras, dou alguns exemplos de áreas de assunto para que não haja confusão e substituição de conceitos. A área de assunto sempre depende de qual problema você resolve usando o desenvolvimento de aplicativos:
- Reserva de bilhetes (se você é desenvolvedor de sistemas de reserva)
- Bancário (se você é desenvolvedor de aplicativos bancários)
- Sistemas operacionais (se você é um desenvolvedor de SO de desenvolvedor)
- Gerenciamento de infraestrutura em nuvem (se você é um desenvolvedor do k8s)
- Virtualização (se você é um desenvolvedor de Docker)
- Monitoramento de desempenho (se você é um desenvolvedor do Prometheus / Grafana)