POCOs != 领域对象?

6
我正在使用ORM处理我的第一个大型项目,我开始意识到ORM会对创建表达性强、传递意图的领域对象构成很大障碍。
也就是说,我们不希望领域对象仅仅是一堆可公开访问的getter和setter。此外,我开始意识到,到处都有IList<T>并不能传达意图,并且可能会引起使用这些对象的开发人员滥用。例如,也许更好的方法是公开ReadOnlyCollection<T>。(顺便说一句,我正在使用.NET和Entity Framework)。而且,我发现自己想要公开一系列从MyDomainObject派生的对象,而不是IList<MyDomainObject>。(这些事情在EF中都不容易做到,也许我需要使用NHibernate或ADO.Net)
我的问题是: 我在尝试以这种方式打造领域对象时是否过头了?这些问题应该只是其他应用程序组件的一部分吗?还是我应该有一个“真正”的领域对象(具有表达式的东西)和一个由ORM填充的“愚蠢”的POCO对象?
(编辑: 系统误吞了我一些尖括号。)
5个回答

2
我的观点是让EF自己完成工作,并创建免费的POCOs。你也可以称它们为DTOs - 它们的角色是作为从内存到持久性和回来的桥梁。至于你的“领域”,我从来没有相信你的DB模式反映了一个连贯的领域模型的想法。因此,我总是在持久性(或仓库)层上创建一个表示业务领域的领域层,将持久性的香肠工厂排除在外。这个领域层可以根据需要混合使用您的DTOs,以创建一个对开发人员有意义的开发人员面向模型。使用工厂模式从DTOs创建领域对象,反之亦然 - 将DTOs保留在客户端代码之外,以便您可以将模式更改与消费者隔离开来。

这需要更多的工作、更多的映射代码等,但这是值得的 - EF已经减少了你的代码,我会说你应该花时间编写领域逻辑和表示,这是使你比代码生成工具更好的原因 :)

祝你好运。


1

(在EF中,这些事情都不容易做到。也许我需要使用NHibernate或ADO.Net。)

没错。EF不支持与NHibernate或自定义解决方案相同的领域和持久性基础设施之间的独立性。

至于暴露的类型,我坚持使用IEnumerable,并在父级上使用Add和Remove方法,通常是自定义集合,但从不使用IList。


1

这是一个非常好的问题 - 当我尝试使用ORM来处理领域对象时,我意识到了这一点。我的领域对象公开类型为IEnumerable的公共属性,返回ReadOnlyCollection,因此唯一的添加集合的方法是在父级上调用自定义的Add方法。

在我看来,不,你并没有过分地打造你的对象。

我完全支持尽可能地封装您的对象,保持字段私有,并提供原子的公共方法,明确显示意图,并确保对象只能存在于有效状态。如果这意味着使用原始的ADO.NET,那就这样吧。对我来说,严格设计领域对象不应该受到DAL技术选择的影响。

然而,我讨厌编写样板式的 DAL 代码,并且使用原始的 ADO.NET 和存储过程编写代码会令我头痛。我所意识到的是,如果你将事件源作为持久化机制来编写封装的域对象的数据访问层(DAL),那么编写 DAL 就变得非常非常非常容易。你只需要一个事件表来存储所有事件的序列化数据。因为域对象本身没有被持久化,所以存储库不能访问域对象上的列表属性也不重要。于是你的工作单元可以“触发”这些事件,查询组件可以处理这些事件,使用简单的 DTO 和 ORM 来填充/更新任何需要使用的表。

这里有一个事件源示例

CQRS和事件溯源实际上是为了提供高可扩展性而设计的,根据“最终一致性”范例,其中包括许多异步操作。然而,即使在不需要这种级别的可扩展性的项目中工作时,我发现以同步方式遵循这些模式可以提供一种机制来完全封装我的领域对象,同时又不必编写单行手工DAL代码,节省了大量时间,并为每个操作(事件)提供了完整的审计跟踪,这也是如果您的系统需要通过消息与第三方系统通信的无价之宝。


1

我尝试在几个项目中使用POCO作为领域对象,但说实话它只适用于简单/小型项目。

我喜欢ORM并且不会停止使用它们。但我总是在orm / repository层之上构建一个领域层。并创建特定的领域对象用于我的应用程序。我使用像automapper这样的映射框架将领域对象与数据对象进行转换。

我向您推荐的是,如果您正在使用实体框架,请停止使用POCO并让EF为您生成数据对象。然后创建领域对象,并让automapper在您的领域层处理映射。

这需要更多工作,但更灵活,易于使用。


0

没有什么规定POCO不能包含你自己定义的复杂对象。使POCO成为POCO的是它与数据状态没有联系,而不是它只能作为对象包含列表。


我对POCO中的自定义属性和复杂对象的概念非常熟悉。EF能够忽略属性并且处理“复杂类型”也很好。但是,当涉及到集合和派生类型时,它就会出现问题。在您的经验中,您是否遇到过ORM使用的集合暴露了过多功能的问题? - Hobbes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接