Value Object是一个糟糕的模式吗?

时间:2009-07-31 16:49:42

标签: design-patterns

使用VO(POCO)是一种糟糕的设计模式吗?有人说对象的所有域逻辑都需要在该对象中。

例如:ProductVO:身份证,姓名,说明

ProductBO:SearchById(int id),Insert(ProductVO newProduct),Update(ProductVO updatedProduct,SearchByKeyword(string word)......

6 个答案:

答案 0 :(得分:8)

所有域逻辑都应该在域对象中,在域对象中...但是有一个强有力的论据,即技术问题,如如何将对象保存到数据库,或记录对象活动,不是域行为,它们是基础架构或应用程序问题,不应该在域对象中......

检查域驱动设计,在此方法中,建议您将持久性逻辑的域相关方面(如持久化/获取对象)分离为单独的类型(也在域层中),称为存储库...但是即使在这里,如何与数据库或其他持久性存储技术进行通信的技术方面也可以分离为基础结构服务。

一种看待这种情况的方法是将服务划分为三组,

  • Infrsastructure Services。与一般技术方面有关的那些 (如通用数据库访问,缓存,日志记录,配置,消息传递等)

  • 应用服务。这涉及与业务领域无关的技术或应用程序设计方面(UI中的MVC模式,屏幕导航,域实体初始化方法等。

  • 域名服务。与业务模型明确相关的服务。 (例如,为特定航班上的航空公司座位创建预订,具有特定的膳食请求和座位分配,以及对指定信用卡的适当交易借记......)

    最后一种“服务”应该在域层,前两个, - 不是......

答案 1 :(得分:5)

  

使用VO(POCO)是一种糟糕的设计   图案?有人说全部   对象的域逻辑需要   在那个对象中。

我认为这里存在很多混淆,因为“价值对象”存在两个几乎完全相互矛盾的定义

  • 一个是“一个有价值语义的对象”,即不可变,经常在施工时验证其正确性。
  • 另一个是“具有状态但没有逻辑的对象”。我想这就是你的意思。最好将其称为数据传输对象,因为该表达式更好地定义。

POCO / POJO也不是一个合适的表达式,因为它并不意味着缺少逻辑,只是不需要特定的超类,接口或字节码增强。

关于你的问题:在没有逻辑的课程中拥有一个域模型,除了看到其他人这样做并且有一个名字的确是非常糟糕的设计 - 这是一种称为 anemic domain model 的反模式。不幸的是,有许多设计糟糕的框架(现在通常被抛弃)需要并促进这种“模式”。

它忽略了面向对象的基本思想:用操作它的逻辑封装数据,并且它通常导致冗长,不灵活和脆弱的代码,因为现在需要显式调用外部逻辑并传递模型,它变为确保无法传递无效数据变得更加困难,并且关于域模型结构的知识广泛传播。

话虽如此,“对象的所有域逻辑都需要在该对象中共存”绝对不是真的 - 有时候有充分的理由提取域逻辑的某些并保留它在不同的课程中:

  • 当它不是真正的域逻辑而是技术方面,如持久性时,应该在一个单独的层中
  • 当应用程序的不同部分的逻辑不同时
  • 一般来说,当它太复杂以至于域类会变得太大,你需要更多地构建它。

但通常,关于对象的域逻辑应该是该对象的一部分,除非您有特定的理由将其放在其他地方

答案 2 :(得分:3)

使用VO可以让你将状态与行为分离,这听起来与OOP不兼容,但是当应用程序的不同方面在考虑到自己的目标时查看状态时,这可能是合适的。

反对VO的一般论点是它们允许无效状态,但是有效性的构成可能会有所不同,具体取决于处理管道中的某个阶段或正在考虑的处理方式。例如,数据录入可能只要求出生年份是过去年份而不是120年前,但学生的资格要求会更严格。可以通过导入或数据输入创建VO,然后将其传递给学生业务逻辑对象,该对象维护对VO的引用并确保其要求的有效性。然后可以传递学生而不是原始VO,从而允许完全面向对象的行为。如果业务逻辑对象通过不可变接口公开VO,这种方法尤其有用。

答案 3 :(得分:2)

价值对象很棒!

为什么在这个世界上,当你只是将名称的规则封装到Name类中时,你想要一直调用“IsValidName(myString)”,然后让编译器确保非-validated name永远不会被传递?

答案 4 :(得分:1)

我认为它们对某些环境(例如面向服务的应用程序)来说是一个很好的模式。

当您想要解耦应用程序的各个层时,使用DTOs通常很有用。 DTO帮助您做到这一点的原因是您可以轻松地序列化DTO,同时理解可以应用于它的任何行为都位于其他位置。

在不需要解耦状态和行为的情况下,我不建议使用此模式,因为它只会使域混乱。

答案 5 :(得分:1)

如果使用得当,设计模式也不错。 对我来说,POCO应该只有对象内逻辑,所有对象间逻辑都属于业务层。