Design patterns 值对象是一种坏模式吗?

Design patterns 值对象是一种坏模式吗?,design-patterns,Design Patterns,使用VO(POCO)是一种糟糕的设计模式吗?有人说,一个对象的所有域逻辑都需要在该对象中结合在一起 例:ProductVO:Id、名称、描述 ProductBO:SearchById(int-id)、Insert(ProductVO-newProduct)、Update(ProductVO-updatedProduct)、SearchByKeyword(string-word)…我认为对于某些环境(例如面向服务的应用程序),它们是一种很好的模式 当您想要解耦应用程序的层时,使用通常是有价值的。D

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

例:ProductVO:Id、名称、描述


ProductBO:SearchById(int-id)、Insert(ProductVO-newProduct)、Update(ProductVO-updatedProduct)、SearchByKeyword(string-word)…

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

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


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

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

所有域逻辑都应该在域层中,在域对象中……但有一个强有力的论点是,技术问题,如如何将对象保存到数据库,或记录对象活动,不是域行为y是基础设施或应用程序问题,不应位于域对象中

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

一种方法是将服务划分为三组

  • 基础设施服务。与一般技术方面相关的服务 (如通用数据库访问、缓存、日志记录、配置、消息传递等)

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

  • 域服务。与业务模式明确相关的服务。(例如,为特定航班上的航班座位创建预订,包括特定的用餐请求和座位分配,以及对指定信用卡的适当交易借记……)

    最后一种类型的“服务”应该在域层,前两种,-而不是


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


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

值对象非常棒

当你可以将一个名称的规则封装到一个名称类中,然后让编译器确保一个未经验证的名称永远不会被传递时,你为什么还要到处调用“IsValidName(myString)”呢

使用VO(POCO)是一种糟糕的设计吗 模式?有人这么说 需要修改对象的域逻辑 一起在那个物体上

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

  • 一种是“具有值语义的对象”,即不可变,通常在构造时验证其正确性
  • 另一个是“一个有状态但没有逻辑的对象”。我想这就是你的意思。最好将其称为数据传输对象,因为该表达式定义得更好
POCO/POJO也不是一个合适的表达式,因为它也不意味着没有逻辑,只是不需要特定的超类、接口或字节码增强

至于你的问题:在没有逻辑的类中拥有一个域模型,除了看到其他人这样做并为其命名之外,没有其他原因,这确实是非常糟糕的设计——这是一种被称为的反模式。不幸的是,有许多设计糟糕的框架(现在普遍放弃)需要并促进这种“模式”

它忽略了面向对象的基本思想:用操作数据的逻辑封装数据,通常会导致冗长、不灵活和脆弱的代码,因为现在需要显式调用外部逻辑并将其传递给模型,因此很难确保无效数据不被传递,而且知识关于领域模型结构的研究已广泛流传

也就是说,“一个对象的所有域逻辑都需要在该对象中放在一起”,这肯定不是真的——有时有很好的理由提取一些域逻辑并将其保存在单独的类中:

  • 当它不是真正的领域逻辑,而是一个技术方面,比如持久性时,它应该在一个单独的层中
  • 当逻辑在不同的PAR中不同时