如果您要在DDD App for CRUD之上安装REST层,您是否会让REST层吐出域模型(就数据而言)(比如GET)?
答案 0 :(得分:22)
通常,您希望能够更改域对象(例如,当您了解有关域的新内容时),而无需更改系统的公共接口/ API。反过来说:如果需要对公共接口进行更改,则不必更改域模型。
因此,从这个角度来看,我永远不会在公共接口上公开我的域对象。相反,我会创建属于公共接口的数据传输对象(DTO)。这样,对我的域和公共API的更改可以独立更改。
答案 1 :(得分:2)
您不应公开DDD模型。这是绝对正确的,因为SOA前端不应该向客户端公开实现细节。您的用户应该依赖于业务功能,而不是实现细节...但是这假设一个很好的设计,将多个,可能是异构的应用程序整合到SOA总线中。
我想补充一点,因为提到CRUD接口让我觉得这可能是SOA滥用的情况,其中SOA原则用于粘合应用程序的层,而不是应用程序网络。 SOA是企业与其系统进行通信的一种方式,它不是实现MVC的一种方式!这么简单却被误解了。例如,仅仅因为您的前端GUI使用服务来访问后端,您就没有“SOA应用程序”。......这意味着什么。
如果这是用于粘合图层的SOA的情况,请修改您的设计并使用适当的设计架构来实现该抽象级别。否则你会错误地解释这里发现的关于不暴露DDD模型而不使用CRUDY的建议,你肯定会最终为服务接口创建一个单独的域模型,然后你必须映射到DDD,这是如此复杂您将需要使用推土机和类似的东西来用不同的名称映射相同的东西,等等,直到我们最终得到一个膨胀的无法维护的混乱......
..小心点。
-Alex
Redzedi是对的,我们需要澄清......
像所有事情一样,这比做起来要复杂得多。序列化复杂的域模型可能非常困难,您最终可能不会在域中放置任何逻辑,贫血模型反模式(http://martinfowler.com/bliki/AnemicDomainModel.html),或者具有单独的贫血模型持久性,即DTO。
我不知道什么是最糟糕的,但两种选择都很糟糕。您应该将模型中的逻辑放在模型中,并且您应该能够在任何地方直接序列化。
根据我多年使用域模型的经验,我认为最好的事情是中间点。是的,正如Fowler和Evans所说,业务对象应该带有逻辑,但不是所有(http://codebetter.com/gregyoung/2009/07/15/the-anemic-domain-model-pattern/)有点贫血症好的服务层是最好的。
例如,发票应该知道其项目,并有一个计算总计的程序,这取决于项目。但发票的项目不需要知道发票。那么当一个项目的成本发生变化时,如果它有一个指向父发票的指针作为循环参考并调用发票的计算总程序会发生什么?
我不相信。我认为这是服务层的任务,谁应首先接收事件然后编排程序,而不必将所有业务对象连接在一起以实现实现并违反业务交互规则,这就是域模型的用途。
-Alex