在ddd实践中,CRUD方法是否应放在模型对象中

时间:2012-06-14 04:33:35

标签: java domain-driven-design crud

我正在尝试实现域驱动设计,代码的基本结构包括以下对象:

Action->Facade->
Service
Model
Repository

您认为CRUD方法应该放在模型中,如下所示:

order.save(new order())

或者像下面这样放在外立面:

addOrderFacade.save(new order())

3 个答案:

答案 0 :(得分:7)

'save'或'delete'方法属于存储库。通常,Save由服务或命令处理程序调用(如果您使用基于命令的方法来更新域)。从CRUD保存处理CU,D得到自己的方法,R部分是有趣的。

如果R为了更新它意味着'GetEntity',那么它可以是与Save一样处理的域存储库(存在多个存储库)的一部分。

但是,如果要读取显示,基本只是将结果返回给用户的查询,则应使用专用于查询的不同存储库,以及简化的只读模型。可以从控制器甚至UI调用此repo。

答案 1 :(得分:2)

我建议不要将它们放在域类中,因为,

你的域类包可以在你的DAO层不同的其他app中的某个地方重用,所以最好在DAO模型上创建另一个层

答案 2 :(得分:0)

惯例是将CRUD方法放在存储库或服务层而不是模型中。实际上,当使用像Spring或Hibernate这样的框架时,你会被诱惑使用这种方法。仅仅因为这个原因通常更容易:

  • 其他开发者期待它
  • 框架支持它
  • 教程和示例假设

然而,从设计的角度来看,有一个强有力的案例可以反对这种方法。它导致anemic domain model,换句话说,只有状态和没有行为(结构)的对象在公平性上并不是非常面向对象的。通过视图,控制器,服务和存储库层需要大量数据传递,并且需要许多“开销”代码来将状态和行为结合在一起。缺乏对规范模型层的关注也可能导致团队之间不匹配,分散的模型。

试图避免这种设计陷阱的方法通常称为domain driven design,由Eric Evans定义。请注意,在DDD中,维基百科页面中仍然存在服务和存储库的位置:

  • 服务:当一个操作在概念上不属于任何对象时。根据问题的自然轮廓,您可以在服务中实现这些操作。服务理念在GRASP中被称为“纯粹制造”。
  • 存储库:检索域对象的方法应委托给专门的存储库对象,以便可以轻松地互换替代存储实现。
  • 工厂:创建域对象的方法应委托给专门的Factory对象,以便替代实现可以轻松互换。

如果您有兴趣,请查看支持DDD的software tools和(仅在下面)DDD示例应用程序。