这真的是DDD吗?

n8w*_*wrl 22 domain-driven-design

我80%肯定我不应该问这个问题,因为它可能会被认为是否定的,我的意思是不会对任何人不尊重,特别是本书的作者.我看过几篇推荐本书及其配套项目的帖子.我没看过这本书,但今天我花了几个小时研究这个项目.虽然看起来非常完整,但我很难分清各种各样的细节.我在自己的设计中苦苦挣扎,如果一个实体发生变化,我必须改变多少,而这个项目并没有让我感到非常舒服.

例如,有一个继承自Person的Employee对象.Person有一个带有名字,姓氏等的构造函数,因此Employee也是如此.私人雇员是名字,姓氏和公共财产的成员.

有一个EmployeeFactory,它知道Employee和Person属性,以及SQL列名称(从读取器中提取值).

有一个带有未实现的PersistNewItem和PersistUpdatedItem方法的EmployeeRepository我怀疑,如果实现的话,将为INSERT和UPDATE语句构建SQL,就像我在CompanyRepository中看到的那样.这些将属性写入字符串以构建SQL.

有一个'数据契约'PersonContract具有与Person相同的私有成员和公共属性,而EmployeeContract继承自PersonContract,如Employee,Person,具有镜像实体的公共属性.

有一个静态的"Converter"类,其中包含将实体映射到Contracts的静态方法

EmployeeContract ToEmployeeContract(Employee employee) 
Run Code Online (Sandbox Code Playgroud)

它将字段从一个复制到另一个,包括Person字段.可能有另一种方式的伴侣方法 - 不确定.

我认为也有单元测试.

总而言之,我计算了5-10个类,方法和构造函数,其中包含有关实体属性的详细知识.也许他们是自动生成的 - 不确定.如果我需要向Person添加"Salutation"或其他属性,我将不得不调整所有这些类/方法?我确定我会忘记一些事情.

同样,我的意思是没有不尊重,这似乎是本书的一个非常详尽的例子.这是DDD的完成方式吗?

Rib*_*die 14

领域驱动设计非常简单.它说:让你的模型类镜像现实世界.因此,如果您有Employees,请拥有一个Employee类,并确保它包含为其提供"Employee-ness"的属性.

你问的问题不是DDD,而是一般的类架构.我认为你对正在考虑的课程的一些决定提出质疑是正确的,但它与DDD无关.它通常与OOP编程设计模式有关.

  • 跟进:您有权质疑Employee是否应该为Person子类.我认为不应该.一个人应该有角色,而员工就是这样一个角色.子类化打开了一堆蠕虫.考虑一下,如果您需要更改域模型中的Person-ness,您也将更改Employee-ness,即使更改与Employee-ness没有任何关系.继承,使用不当,使域模型更弱.继承,使用不当,使软件变得更糟. (4认同)
  • 我认为令人惊讶的是,我在这个答案上获得了10票.自从我写这篇答案以来的几年里,我学到了很多关于DDD的知识,并发现它比这个概念的简单部分更加详细和复杂.这不是一个错误的答案,但它肯定是非常肤浅的. (2认同)

Cha*_*tin 10

DDD是足够新的(至少在某些意义上说)可能有点早,准确地说"它是如何完成的".尽管如此,这个想法已经存在了很长一段时间,尽管我们并没有为它做出一个很酷的名字.

在任何情况下,简答题(IMAO)都是"是的,但是......"进行域驱动设计的想法是非常明确地对域进行建模.你正在看的是一个域模型,也就是说一个面向对象的模型,用于描述问题域语言中的问题域.这个想法是,域模型,因为它模拟"现实世界",对变化相对不敏感,也倾向于本地化变化.因此,如果您对Employee的内容有所改变,可能是通过添加邮件地址和物理地址,那么这些更改将相对本地化.

但是,一旦你拥有了那个模型,你所拥有的东西仍然是建筑决策.例如,您有未实现的持久层,这可能只是SQL的构造.它也可以是一个Hibernate层,或者使用Python pickling,甚至可以像Google AppEngine分布式表结构一样狂野.

问题是,这些决策是与域建模决策分开制定的,并与其他理由一起制定.

我尝试过一些好结果的东西是用Python做域模型然后用它构建模拟器而不是实现最终系统.这使得客户可以尝试一些东西,并且还可能允许您对最终实施必须确定的事项进行定量估计.


Ste*_*owe 9

对我来说,DDD与"仅仅"模型驱动设计的不同之处在于"聚合根"的概念,即应用程序只允许包含对聚合根的引用,并且通常只有聚合根的存储库class,而不是聚合根使用的类

这大大清理了代码; 替代方案是每个模型类的存储库,它"仅仅"是一个分层设计,而不是DDD