对于应用程序开发人员,我认为编写具有域对象的应用程序的传统范例是可以持久化到底层数据存储(SQL数据库以供参数使用),就是编写域对象,然后编写(或生成)表结构。域对象的外观与底层数据存储的结构之间存在紧密联系。因此,如果要向域对象添加一条信息,请将该字段添加到代码中,然后将列添加到相应的数据库表中。都熟悉了?
对于具有良好定义结构的数据存储(这主要是关于SQL数据库,其中表和列是预定义和修复的),这一切都很好,但现在是无处不在的SQL的许多替代方案数据库存在,这些通常不会以这种方式约束数据。例如,MongoDB是一个 NoSQL 数据库,您可以将数据划分为集合,但除此之外,没有数据结构。如果要添加新字段,则不要定义新列。
现在提出一个问题:考虑到像MongoDB这样的数据存储的灵活性,如何在代表这些数据的域对象中实现类似的灵活性?因此,例如,如果我使用Spring并创建自己的域obejcts,当我向我的数据添加“middleName”字段时,如何避免在我的域对象中添加“middleName”字段?我正在寻找某种机制/方法/框架来动态检查数据,并在我的域对象中访问它,而不必每次都进行代码更改。欢迎所有想法。
答案 0 :(得分:2)
我认为你有几个选择:
您可以使用动态编程语言而不是域对象(例如clojure)
如果您已经修复了使用java,那么mongo java驱动程序将返回DBObject中的数据,该数据本质上是一个Map。因此默认行为已经提供了您想要的内容。只有当您使用像morphia(或spring-data)这样的库将DBObject映射到域对象时,您甚至必须担心域对象。
但是,如果我使用java,我会坚持使用morphia映射的域对象的标准约定,因为我认为添加字段与利益相比是一个非常小的不便。
答案 1 :(得分:1)
我认为这个问题具有根本性的矛盾性 一方面,您希望拥有域对象,即表示问题域的数据(和行为)的对象 另一方面,您说您不希望您的域对象明显受到数据更改的影响 但是,当您拥有代表问题域的对象时,您希望这样做 - 代表您的问题域 因此,例如,如果添加了中间名,那么现实生活中的“用户”实体的表示应该更改以适应现实生活中的用户;也许不仅通过将这段数据添加到您的对象,还添加一些相关的行为(中间名的验证,或与其相关的一些功能)。
在本质上,我在这里要说的是,当你拥有(经典的OO)域对象时,你可能需要改变你的行为/功能以及你的数据,因为你没有任何自动方式改变行为,自动更改数据的问题变得无关紧要。
如果您不希望与您的数据相关联的行为,那么您必须拥有DTO,并且@Kevin的答案正是您所寻找的。 p>
答案 2 :(得分:1)
老实说,这听起来更像是你正在寻找某种黑盒DTO,就像你描述的那样,字段被添加或删除"任意"取决于数据。这使我倾向于建议一个简单的Map
来完成这项工作。如果您的域模型不断变化,您就无法真正拥有域驱动设计。