查找表:它们是否在域模型中泄漏?


10

您正在建立一个跟踪公司的系统。这些公司有联系人。这些联系人通常都是专家,只回答某些类型的问题,例如帐单/付款,销售,订购和客户支持。

使用域驱动设计和洋葱架构,我使用以下类型对它进行了建模:

  • 公司
    • 有联络人
  • 联系
    • 有联系方式
  • ContactType(枚举)
  • CompanyRepository(接口)
  • EFCompanyRepository(在外部程序集中定义,使用EntityFramework,实现CompanyRepository)

对于如何为该应用程序建模数据库,我们的团队意见分歧。

A面:精益DDDers:

  • 定义哪些ContactTypes对一个联系人有效是Domain的工作。向数据库中添加表以验证是否未保存未知的ContactType是域泄漏的迹象。它将逻辑传播得太远了。
  • 将静态表添加到数据库和相应的代码是浪费的。在此应用程序中,数据库解决了一个问题:保留事物并将其还给我。编写一个额外的表和相应的CRUD代码很浪费。
  • 更改持久性策略应尽可能容易。更改业务规则的可能性更大。如果我决定SQL Server花费太多,则不需要重新构建放在架构中的所有验证。

B面:传统主义者[这可能不是一个好名字。DBCentrists?]:

  • 在数据库中存储没有读取代码就没有意义的数据是一个坏主意。报表和其他使用者必须自己重复值列表。
  • 按需加载数据库类型字典的代码并不多。不用担心
  • 如果更改的源是代码而不是数据,那么当更改时,我将不得不部署位而不是简单的SQL脚本。

哪一方都不对或错,但从长远来看,其中一方可能会更有效率,计算初始开发,错误等的开发时间。这是哪一方-还是有更好的折衷办法?其他编写这种样式的代码的团队做什么?


我更喜欢在数据库中具有查找表,并具有基于我的应用程序代码中的查找表为我生成枚举的代码(.NET中的T4模板)。
程序员

@JasonHolland T4模板是否实际执行查询?否则,我不确定它如何生成比预期名称更空的枚举。
画了


对于具有静态值的表,您需要编写多少CRUD代码?编写脚本并完成。
JeffO

2
传统的CRUD主义关于“好吧,报告毫无意义”的论点并非一帆风顺。一旦您引入了系统要承担的其他一些责任(即报告),您就会发现需要适当处理的业务需求。数据库在那里存储和加载应用程序自己的受保护状态;允许对其进行报告会在您的应用程序和需要报告的人员之间建立耦合。如果DDD涉及任何内容,那么它就是将这些上下文分开。
马特

Answers:


4

通过采用DDD和洋葱体系结构,您已确定数据库是您的域模型的第二位。这就是说,除了模型之外,没有其他人在数据库上进行操作。如果传统主义者不喜欢这样做,那么他们应该首先反对使用DDD。

第一件事很清楚:您需要模型中的“查找表”。您的模型需要区分不同类型的联系人。这意味着,它将保留所有类型的强类型列表。还需要将那些强类型映射到序列化到数据库的值。该映射可以在数据库模块内部。但是所有可能类型的列表仍将在模型中。而且,如果模型要成为事实的单一来源,那么它就不能在数据库内部。或者至少,当列表在模型中更改时,它需要在数据库中更改。而且没有!


2

当领域对象跨越过程边界时,它们就不再是领域对象。即使数据库只是一个持久性存储,在将来的某个时候,业务需求也将导致更改与持久化历史不一致的domaim模型,并且无论如何您都将需要一个反腐败层....

就是说,我认为您的DBCentrists正在错过这条船。域建模者说他们需要一个持久性存储。“报告和其他使用者”需要他们可以查询的内容-带有适当索引的内容,如注释中所述。

谁引入了一个约束,即所有这些不同的问题都需要由一个数据库来支持?如果您继续这样做会发生什么。

搜索关键字:CQRS。


1

我发现最好将枚举作为字符串表示形式存储在数据库中,并且不包括查找表。

显然,这样做的不利之处在于它使用了更多的磁盘空间并且没有被标准化。

好的一面是,该字段在db中保留了其含义,例如,您最终不会获得与枚举的int值相对应的幻数,并且不必在枚举更改时管理查找表的版本控制。

不确定我是否将其描述为DDD与Trad的区别。我认为最好是数据库中心主义者vs代码


想知道这些天数据库本身是否具有这种枚举功能
herzmeister 2015年

我想这取决于数据库,您可以使用MSSQL进行各种疯狂的CLR操作。但是我坚信“ DB不好,代码良好”这方面
Ewan

@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html,Ewan一旦您接受了存储过程,数据库就是代码。(PLv8很棒)。
西里西亚人2015年

@Sirisian您知道它可以融合吗?我有一个类似的问题。“有规模吗?”
伊万2015年

您是说将枚举转换为字符串会产生叉积吗?可能不是。我不确定如何实现,但是它比使用单独的表要快。它可以缩放。还发现了这一点:stackoverflow.com/questions/2318123/…5年后似乎仍然是有效的评估。(我倾向于编写与PostgreSQL高度相关的程序,因此我使用了所有功能,但并不是每个人都能做到)。
西里西亚人2015年

0
  • 只要您使用关系数据库,就应该在合理的范围内保持表规范化。规范化有助于防止插入和更新异常。
  • 单应用程序与一个数据库的关系不再常见,多个应用程序可以使用多个数据库,而一个数据库可以由多个应用程序使用,因此让数据库尽可能地强制执行引用完整性是一件好事。
  • RDBMS是您的朋友。
  • 您可以改用键值存储,然后执行代码中的所有操作。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.