Service 在应用程序服务参数中使用泛在语言

Service 在应用程序服务参数中使用泛在语言,service,parameters,arguments,domain-driven-design,Service,Parameters,Arguments,Domain Driven Design,泛在语言(UL)是在整个有界环境中使用的,包括领域模型和应用层,对吗?好啊然后,应用程序服务的方法的名称属于UL。但是该方法的参数,因为域对象不应该向用户公开,不会(不能)是UL的术语。如果您使用UL词汇表命名方法args,那么您将在应用程序外部公开域对象 如何解释命名应用程序服务参数的矛盾 也许这个问题看起来有点哲学性,但DDD也是,它是一种软件开发哲学,基于UL 更新 有人要求举个例子,而不仅仅是哲学。假设我们的域名是关于一家销售产品的商店。应用程序服务的一种方法可以是: 添加Product

泛在语言(UL)是在整个有界环境中使用的,包括领域模型和应用层,对吗?好啊然后,应用程序服务的方法的名称属于UL。但是该方法的参数,因为域对象不应该向用户公开,不会(不能)是UL的术语。如果您使用UL词汇表命名方法args,那么您将在应用程序外部公开域对象

如何解释命名应用程序服务参数的矛盾

也许这个问题看起来有点哲学性,但DDD也是,它是一种软件开发哲学,基于UL

更新

有人要求举个例子,而不仅仅是哲学。假设我们的域名是关于一家销售产品的商店。应用程序服务的一种方法可以是:

添加ProductToShoppingCart(产品产品,ShoppingCart ShoppingCart)


但产品和ShoppingCart是域模型的实体/价值对象,我们不应该将其公开给客户


所以参数应该是DTO或基本类型。但这种类型不属于UL。产品和ShoppingCart确实属于UL,应该是该方法的参数,但这样做会打破向客户公开域的规则。

我认为应用程序服务层应该尽可能多地反映UL,而不会泄露域模型技术解决方案的细节。换句话说,您希望应用程序服务公共API使用泛在语言的术语表示,但不希望客户机代码在域模型层上耦合

如果使用UL词汇表命名方法args,则将在应用程序外部公开域对象


这是一个误解:方法参数应该尽可能使用UL术语命名,但参数类型不应该利用域包中定义的类型。这仅仅是出于技术原因,因为隔离允许您独立于公共应用程序的API更改域模型。

讨论一个示例比讨论“原理”要好得多。但是

矛盾的是,大多数DDD设计实际上没有严格遵循UL标准。例如,看看几乎所有公开的“DDD”设计

“域”(即值对象和实体)通常被建模为仅数据的“对象”,几乎没有任何业务逻辑。就在这里,方法名已经离开了UL,并且纯粹是技术领域的(通常是setter、getter)

服务也是如此。服务根本不是“域”的一部分。试着告诉一个生意人你已经实现了一个
密码服务
,我保证你会茫然地回头看。服务在外部也是纯技术性的,其中包含一些与业务相关的方法,这些方法实际上可能属于某个价值对象或实体

因此,尽管我同意“哲学”部分的观点,但埃里克·埃文斯(Eric Evans)所定义的今天使用的构建块远远不是该哲学的最佳实现


请看一下我关于这个问题的演示文稿:

关于上述演示文稿和组成员资格重构示例:您的解决方案无法识别组成员可能是其他组,此时需要执行IO以获取成员,因此,沃恩在服务的帮助下对这个用例进行建模。你可以一直做
group.hasMember(potentialMember,groupMembershipResolver)
,但这意味着你的域不是“纯”域,可以间接执行IO。我一直在阅读。。。持久性选项1毫无意义。您的域逻辑现在在基础设施细节中丢失,您无法对其进行单元测试。持久性选项#2还泄露了域中的基础设施细节。这都是一个权衡的问题,但建议远比大多数存储库模式实现糟糕。@plalx您是对的,成员资格检查是分开的,因为设计想要将“IO”与
分开。然而,这是完全武断的。这是设计出的问题,然后通过离开“域”解决。这是错误的。我不在乎(你也不应该在乎)一个
小组如何决定某个东西是否是成员。也许它确实使用了一些合作者,也许它只需要检查它的实例变量。这有什么关系呢?大多数DDD纯化论者都会反对在实体中注入任何类型的服务,因为服务不是实体状态的一部分,这使得可测试性更加困难。如果您没有任何服务注入,那么您也没有测试域模型所需的模拟和存根,您的持久性策略也不必关心服务注入。据我所知,大多数开发人员倾向于同意,从域对象中删除所有类型的IO是一个更好的权衡。“但是产品和ShoppingCart是域模型的实体/价值对象,我们不应该将其公开给客户。”-为什么?如果我们不公开“域”,我们应该公开什么?非域,即技术对象?根据DDD,如果我没有误解它,您可以向客户端公开域属性/值对象,但您不应该。。。这不是“强制性的”,但我认为这是一个很好的做法。例如,沃恩·弗农使用原语,而不是域对象。应用层是域模型的直接客户端,从外部保护它,它将DTO/基本类型映射到域对象,反之亦然。它暴露了国家,而不是全部的目标。沃恩·弗农(Aughn Vernon)有关于这个主题的书,我没有,就权威而言,我猜他赢了。不过,我完全不同意他的解释。我已经做过很多类似的架构,它们是不可维护的。或者更确切地说,还有更多可维护的替代方案,它们涉及到坚持域,而不是介绍