1

对于应用程序开发人员,我认为使用可以持久保存到底层数据存储(为了参数的 SQL 数据库)的域对象编写应用程序的传统范例是编写域对象,然后编写(或生成)表结构。域对象的外观与底层数据存储结构的外观之间存在紧密耦合。因此,如果您想向域对象添加一条信息,请将该字段添加到您的代码中,然后将一列添加到相应的数据库表中。都熟悉吗?

这对于具有良好定义结构的数据存储(我主要谈论 SQL 数据库,其中表和列是预定义和固定的)来说非常好,但是现在存在许多替代无处不在的 SQL 数据库并且这些通常不会以这种方式限制数据。例如,MongoDB 是一个NoSQL数据库,您可以将数据划分为集合,但除此之外没有数据结构。当您要添加新字段时,您无需定义新列。

现在问题来了:考虑到像 MongoDB 这样的数据存储的灵活性,如何在表示这些数据的域对象中实现类似的灵活性?因此,例如,如果我使用 Spring 并创建自己的域对象,当我向我的数据添加“middleName”字段时,如何避免必须向我的域对象添加“middleName”字段?我正在寻找某种机制/方法/框架来动态检查数据并在我的域对象中访问它,而不必每次都更改代码。欢迎所有想法。

4

3 回答 3

2

我认为你有几个选择:

  1. 您可以使用动态编程语言并且没有域对象(例如 clojure)

  2. 如果你固定使用 java,mongo java 驱动程序会返回 DBObject 中的数据,它本质上是一个 Map。所以默认行为已经提供了你想要的。只有当您使用 morphia(或 spring-data)之类的库将 DBObject 映射到域对象时,您才需要完全担心域对象。

但是,如果我使用 java,我会坚持通过 morphia 映射的域对象的标准约定,因为与好处相比,我认为添加字段是一个非常小的不便。

于 2012-08-17T14:59:16.687 回答
1

我认为这个问题本质上是自相矛盾的——
一方面,你想要拥有域对象,即代表你的问题域的数据(和行为)的对象。
另一方面,您说您不希望您的域对象受到数据更改的显式影响。
但是当你有代表你的问题域的对象时,你只想这样做——代表你的问题域。
因此,例如,如果添加了中间名,那么您对现实生活中的“用户”实体的表示应该改变以适应现实生活中的用户的这种变化;也许不仅通过将这条数据添加到您的对象,还添加一些相关的行为(中间名的验证,或与之相关的一些功能)。

本质上,我在这里想说的是,当您拥有(经典 OO)域对象时,您可能需要更改您的行为/功能以及您的数据,因为您没有任何自动方式来更改您的行为,自动更改数据的问题变得无关紧要。

如果您不希望与您的数据相关联的行为,那么您基本上拥有 DTO,@Kevin 的答案就是您要寻找的。

于 2012-08-18T03:02:33.060 回答
1

老实说,这听起来更像是您正在寻找某种黑盒 DTO,就像您所描述的那样,根据数据“任意”添加或删除字段。这使我倾向于建议一个简单Map的工作。如果您的领域模型不断变化,那么您就不可能真正拥有领域驱动的设计。

于 2012-08-18T03:08:19.150 回答