11

我的一些领域类变得相当丰富:它们实现了一个有趣的可比性,可能有加、减、乘和 div,许多都有一些方便的 getter,它们调用服务并确定复杂的事情。最重要的是,它们具有正确的属性。我将它们用于正常的“数据库事务”,并且有时我只想要一个具有所有这些方法但可能不想保存它的对象。

我的队友确信这非常糟糕,并建议我应该使用 DTO(数据传输对象),据我所知,这将是一个 POGO/POJO,其中一个域类的代码复制/粘贴。这似乎真的不干,我看不到好处。不时将域对象用作常规对象有什么问题吗?我错过了 DTO 的重点吗?

4

2 回答 2

6

Grails 域类的命名有些错误,因为应用程序的域层通常由持久类和非持久类组成。但 Grails 域类始终是持久的。您可以拥有非持久域(传统意义上的)类,但它们必须位于 src/groovy 或 src/java 中。这可能令人沮丧,因为域层在应用程序中被分成两个地方。我们已经请求了非持久域类,例如类似static persistent = false或类似的东西,但它还没有实现。

我认为,如果您想利用域类的非持久性特性(例如验证、依赖注入等),那么最好有一些可以由数据库支持但不是的类。您只需要在代码中记录它或有某种约定,例如特殊的包结构或命名约定。save()如果您从不调用、list()、等GORM 方法,findAllByFoo()则不会有任何数据库访问。

就 DTO 而言,它们可以是 un-DRY,但有一个插件可以提供帮助 - 请参阅http://grails.org/plugin/dto。它已经有一段时间没有更新了,但我很确定它仍然有效。它有一个很好的特性,它将使用语法从持久域类实例创建 DTO 实例domainObj as DTO。您确实需要在类之间保持更改同步,但最初的 DTO 生成是通过脚本自动生成的。

于 2012-08-14T04:28:38.963 回答
1

我认为你在正确的道路上。

1 - 当你必须创建一个类来处理一个域类时,你使你的模型更加耦合。您正在创建更多依赖项,这显然很糟糕。您的对象应该能够照顾自己。

2 - 你的朋友正在谈论的模型实际上被称为贫血域模型,其中你的数据与程序的逻辑分离,它首先被 Martin Fowler 描述为反模式。逻辑和数据之间的这种分离在过程编程中非常有用,但在面向对象编程中却没有(OOP 的目的正好相反)。

3 - 减少代码重用。

4 - 一旦您必须初始化与数据分离的逻辑,就更难测试。同时,数据会通过您的系统泄漏。

DTO 是你可以使用的东西,当然。但不建议您这样做。它最初的设计目的是通过流程或层来传输数据(对象)。然后,由于某种原因,人们开始在层之间使用它,这是不值得的。使您的程序更加复杂(一旦您将这些实体分布在您的应用程序中)并且它允许全局访问。

您所做的称为富域模型,使用它没有问题。但是,你当然应该小心。如果你发现你的类承担了太多的责任,那么也许是时候设计另一个类来提供帮助了(也许你违反了SRP原则)。

看看如何在 Grails 中设计域对象。他们鼓励您编写丰富的模型(验证、数据库事务等)。

于 2012-08-11T23:31:28.533 回答