Tabelas de pesquisa: elas são um vazamento no modelo de domínio?

10

Você está construindo um sistema que monitora as empresas. Essas empresas têm contatos. Esses contatos geralmente são especialistas que respondem apenas a certos tipos de perguntas, como cobrança / pagamento, vendas, pedidos e suporte ao cliente.

Usando o Design Orientado a Domínio e uma Arquitetura de Cebola, modelei isso com os seguintes tipos:

  • Companhia
    • Possui contatos
  • Contato
    • Tem tipos de contato
  • Tipo de contato (enumeração)
  • CompanyRepository (interface)
  • EFCompanyRepository (definido em uma montagem externa, usa EntityFramework, implementa CompanyRepository)

Nossa equipe tem uma opinião dividida sobre como modelar o banco de dados para este aplicativo.

Lado A: Os DDD Lean:

  • É o trabalho do domínio definir quais ContactTypes são válidos para um contato. Adicionar uma tabela ao banco de dados para validar que ContactTypes desconhecidos não são salvos é um sinal de domínio com vazamento. Ele espalha a lógica muito longe.
  • Adicionar uma tabela estática ao banco de dados e o código correspondente é um desperdício. Nesta aplicação, o banco de dados resolve um problema: persistir e devolver para mim. Escrever uma tabela extra e o código CRUD correspondente é um desperdício.
  • Alterar a estratégia de persistência deve ser o mais fácil possível. É mais provável alterar essas regras de negócios. Se eu decidir que o SQL Server custa muito, não quero reconstruir toda a validação que coloquei no esquema.

Lado B: Os tradicionalistas [provavelmente não é um nome justo. Os DBCentrists?]:

  • É uma má idéia ter dados no banco de dados que não façam sentido sem a leitura do código. Relatórios e outros consumidores precisam repetir a lista de valores.
  • Não é muito código para carregar seus dicionários do tipo db sob demanda. Não se preocupe com isso.
  • Se a fonte disso for código e não dados, terei que implantar bits em vez de um script SQL simples quando ele mudar.

Nenhum dos lados está certo ou errado, mas um deles é provavelmente mais eficiente a longo prazo, contando o tempo de desenvolvimento para o desenvolvimento inicial, bugs etc. De que lado está - ou há um compromisso melhor? O que as outras equipes que escrevem esse estilo de código fazem?

Desenhou
fonte
Prefiro ter tabelas de pesquisa no banco de dados e código (modelos T4 no .NET) que gera as enumerações para mim com base nas tabelas de pesquisa no código do meu aplicativo.
programador
@JasonHolland O modelo T4 realmente executa uma consulta? Caso contrário, não tenho certeza de como ele gera mais do que uma enumeração vazia com o nome esperado.
Drew
2
sim, ele realiza uma consulta. Dê uma olhada em developerhandbook.com/c-sharp/t4-templates-for-lookup-tables e erraticdev.blogspot.com/2011/01/…
programador
Para uma tabela com valores estáticos, quanto código CRUD você precisa escrever? Script e pronto.
JeffO 27/10/15
2
O argumento tradicionalista do CRUD sobre 'bem, não fará sentido para reportar' é um não-inicial. Assim que você introduz alguma outra responsabilidade que o sistema possui (ou seja, relata), você encontra um requisito comercial que precisa ser tratado adequadamente. O banco de dados existe para armazenar e carregar os aplicativos, estado protegido; permitir que ele seja relatado cria um acoplamento entre seu aplicativo e as pessoas que precisam dos relatórios. Se DDD é sobre qualquer coisa, é sobre separar esses contextos.
Matt

Respostas:

4

Ao adotar a arquitetura DDD e onion, você decidiu que o banco de dados é o segundo em seu modelo de domínio. Isso significa que não haverá mais ninguém executando operações no banco de dados que não seja o modelo. Se tradicionalistas não gostam disso, eles deveriam ter se oposto ao uso de DDD em primeiro lugar.

A primeira coisa é clara: você precisa da "tabela de pesquisa" no modelo. Seu modelo precisa diferenciar entre diferentes tipos de contatos. Isso significa que ele mantém uma lista fortemente tipada de todos os tipos. Também é necessário mapear esses tipos fortes para valores serializados no banco de dados. Esse mapeamento pode estar dentro do módulo de banco de dados. Mas a lista de todos os tipos possíveis ainda estará no modelo. E se o modelo deve ser uma única fonte de verdade, não pode estar dentro do banco de dados. Ou, pelo menos, quando a lista é alterada no modelo, ela precisa ser alterada no banco de dados. E sem buts!

Eufórico
fonte
2

Objetos de domínio deixam de ser objetos de domínio quando cruzam um limite do processo . Mesmo que o banco de dados seja apenas um armazenamento de persistência, em algum momento no futuro as demandas dos negócios causarão uma alteração no modelo domaim que é inconsistente com o histórico persistente, e você precisará de uma camada anticorrupção de qualquer maneira ....

Dito isto, acho que seus DBCentrists estão perdendo o barco. Os modeladores de domínio estão dizendo que precisam de um armazenamento de persistência. "Relatórios e outros consumidores" precisam de algo que possam ser consultados - algo com índices decentes, como foi observado nos comentários.

Quem introduziu a restrição de que todas essas preocupações diferentes precisavam ser suportadas por um banco de dados? O que acontece se você insistir nisso.

Pesquisar palavra-chave: CQRS.

VoiceOfUnreason
fonte
1

Eu achei melhor armazenar enumerações como sua representação de string no banco de dados e não incluir uma tabela de pesquisa.

Obviamente, a desvantagem disso é que ele usa mais espaço em disco e não é normalizado.

O lado positivo é que o campo mantém seu significado no banco de dados, você não acaba com números mágicos correspondentes ao valor int da enumeração, por exemplo, e não precisa gerenciar a versão de uma tabela de pesquisa quando a enumeração muda.

Não tenho certeza se eu caracterizaria isso como uma diferença DDD vs Trad. É mais um código de banco de dados vs centralista é melhor na minha opinião

Ewan
fonte
perguntando se os bancos de dados próprios têm essa característica enum estes dias
herzmeister
Eu acho que isso depende do banco de dados, você pode fazer todo tipo de coisa louca do CLR com o MSSQL. Mas estou firmemente com o 'mau DB, código bom' lado quando se trata de tais coisas
Ewan
@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html , Ewan O banco de dados é código quando você adota os procedimentos armazenados. (PLv8 é maravilhoso).
31415 Sirisian
@ Sirisian você sabe que isso mistura coisa? Eu tenho uma pergunta semelhante. "ele escala?"
Ewan
Você quer dizer que faz um produto cruzado para transformar o enum em uma string? Provavelmente não. Não tenho certeza de como é implementado, mas é mais rápido do que usar uma tabela separada. Escala. Encontrei isso também: stackoverflow.com/questions/2318123/… Ainda parece uma avaliação válida 5 anos depois. (Eu costumo escrever programas altamente acoplados ao PostgreSQL, então uso todos os recursos, mas nem todos podem fazer isso).
Sirisian 28/10/2015
0
  • Enquanto você estiver usando um banco de dados relacional, mantenha as tabelas normalizadas em uma extensão razoável. A normalização ajuda a impedir a inserção e atualização de anomalias.
  • O relacionamento de um aplicativo <-> um banco de dados não é mais comum, vários aplicativos podem usar vários bancos de dados e um único banco de dados pode ser usado por vários aplicativos; portanto, é bom que o banco de dados imponha a integridade referencial o máximo possível.
  • O RDBMS é seu amigo.
  • Você pode usar um armazenamento de valor-chave e fazer tudo no código.
Tulains Córdova
fonte