问题标签 [ddd-service]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
domain-driven-design - 域驱动设计中 CQRS 实现中命令/查询的单独应用程序服务?
在使用领域驱动设计实现 CQRS 时,我们将命令接口与查询接口分开。
我的理解是,在域级别,这会显着降低域模型中的复杂性(尤其是在使用事件溯源时),您的读取模型将不同于您的写入模型。因此,对于您的读写有界上下文,这看起来像是一个单独的域服务。
在应用层面,我们是否需要一个单独的应用服务来实现我们域的读写分离?
在这件事上我一直在扮演魔鬼的拥护者。我的想法是它可能是矫枉过正,要求客户知道其中的区别。但后来我想到了一个消费网络服务如何使用它。一般来说,它会发出读取请求和写入请求,这意味着它已经知道了。
我看到了更清洁的应用程序服务的好处。
domain-driven-design - 使用 DDD 实现用户定义的业务规则
假设我有一个应用程序,让用户创建要应用于域实体的业务规则。规则可以是条件和多个操作的组合,如果条件评估为真,则执行相应的操作。此规则由用户以自由格式的文本格式创建,然后将其转换为规则引擎可以理解和执行的专有格式。
例如,对于员工管理系统,如果有业务规则来检查员工是否在当前角色工作超过一年并且表现好于预期,则可以晋升为下一个角色,加薪 10%。此业务规则可由用户输入,如下所示。
条件:Employee.CurrentRoleLength > 1 && Employee.ExceededExpectations()
操作:Employee.PromoteToNextRole() | Employee.GiveSalaryIncrement(10)
请注意,多个操作用|分隔。. 同样为了执行这个规则,应用程序使用一个单独的规则引擎类库来解析这个条件和两个动作到一个专有的格式,比如说,ExecutableScript也在规则引擎类库中定义。
现在为了使用 DDD 对这个需求进行建模;我想出了以下域对象。
规则(实体)
条件(值对象)
操作(值对象)
其中 Rule 是一个实体,它包含一个条件值对象和一个操作值对象列表,如下所示。
基于上述领域模型,我有以下问题。
如何在不依赖外部规则引擎的情况下解析和执行条件和操作。我理解域层不应该对外层有任何依赖,应该局限于它自己的。
即使我在它们的域对象之外解析条件和操作,它们解析的 ExceutableScript 值仍然需要存在于它们中,这仍然需要依赖于外部规则引擎。
是否只是 DDD 不是这种情况的正确方法,我走错了方向。
对不起,很长的帖子。任何帮助将不胜感激。
谢谢。
domain-driven-design - DDD 域服务
我有一个发票聚合根,在某些时候可以发送到会计外部 Web 服务,并通过保留从该服务获得的一些 ID/号码来标记为已发送。
在 DDD 中执行此操作的正确方法是什么?
以下是我的想法:
第一种方法:
有一个具有功能的发票AggregateRoot SendToAccounting
,并注入域服务/接口,它将发票发送到会计,并在会计软件中检索一些“id / code”,并设置AccountingSoftwareId
属性
第二种方法:
与第一种方法类似,但域服务应该负责这样的持久化:
第三种方法:
域服务将完全负责封装此行为
domain-driven-design - 这是域还是应用程序服务
我正在使用 DDD 构建身份验证微服务/域,但我仍然无法识别每个服务的所属位置。此时我不确定身份验证服务属于域服务还是应用程序服务。
我应该将此行为包装在域服务中,并通过应用程序服务公开响应对象,还是应该保持原样 - 作为应用程序服务。
node.js - ddd:跨越多个模型的逻辑,它应该去哪里?
我正在开发一个系统,并试图将 ddd 与 node.js 一起使用。这是系统的一个示例,从高层次上看:
业务逻辑规定,只有患者或患者、科室列表中某个科室成员的医生才能查看其医疗信息。我最初认为它应该在一个单独的域服务中,因为它似乎跨越实体,但缺点是需要其他服务调用权限服务,我认为服务不应该调用其他服务。如果我放置在实验室和药物实体中,那么我就是重复代码并且违反了干法。如果我添加到部门域服务,那么我正在调用另一个服务。从ddd的角度来看,这样的逻辑属于哪里?
c# - DDD - 具有可选状态的行为:服务/值对象?
遵循 DDD 实践,我在实现小型 AES 加密器/解密器(包装 .NET AesCryptoServiceProvider
)时遇到了问题。
如您所见,.NETAesCryptoServiceProvider
是有状态的——它需要一个键作为属性。但据我了解,服务不应该是有状态的。
- 关键是属性(而不是方法参数)是这里的主要问题吗?
- 您将如何以 DDD 方式实现该类?
- 在某些情况下,使用给定密钥初始化提供程序似乎很有用且有效(如果要经常使用该密钥)。有状态服务是否有理由或替代方案?
我想我们可以在每个方法调用上实例化一个新的 Provider,但这似乎非常浪费。我们可以实施缓存来减少浪费,但整个事情开始感觉过度设计。
我想出的另一种选择是创建一个Aes256CbcCryptorFactory
代替。工厂CreateCryptor(byte[] key)
返回一个Aes256CbcCryptor
实际上是有状态的值对象。如果需要进行多次加密调用,消费服务现在至少可以将此对象保留在其方法之一的范围内。
另一方面,这样的消费服务仍然不能将值对象存储在它的一个属性中,因为这样做会使该服务成为有状态的。
- 看到有一些好处,这是做的事情吗?这种行为类型对于值对象来说似乎非常有用,但至少我们可以有一些临时状态。
domain-driven-design - 基础设施存储库调用域服务
我有一个应用程序服务 (AppService) 和一个从外部数据提供者读取数据的基础架构存储库 (InfraRepo)。AppService 调用 InfraRepo 并向客户端返回数据。我有以下需求:我有一些过滤条件和业务逻辑。为此,我创建了一个域服务 (DomainService) 并将其注入 InfraRepo。从外部数据提供者(在 InfraRepo 中)检索数据后,我调用域服务,将数据传递到那里,然后取回结果。然后我将结果返回给映射到 Dto 并返回给客户端的应用服务。在基础架构存储库中调用域服务是否正确。
domain-driven-design - DDD - 第三方 API 接口应该在哪里?
如果我们考虑一个标准的持久性存储库,那么解决方案很简单。我们将 IStuffRepository 放在领域层,将 StuffRepositoryImplementation 放在基础设施层。
但是,当我们想要包装第三方 API 时,好的模式是什么?
我们可以应用相同的模式,在域层有一个 IStuffGateway,在基础设施层有一个 StuffGatewayImplementation。
但是这种方法存在一个问题。当我们考虑持久层时,我们可以控制我们持久化的数据。但是当我们考虑第三方API时,我们没有控制权,这意味着我们可以尝试拥有一定的接口签名,但它必须受到我们包装的内容的影响。因此,如果我们更改实现(将第三方替换为另一个),接口签名可能会更改,并且域也会更改。
另一种方法可能是将接口移到域外,并将其放入基础设施层,并带有它的实现。这样,应用层就可以毫无问题地使用它(并保持域完整)。但是这种方法从域中删除了重要的概念,从我的角度来看,这似乎很糟糕。
对此有参考意见吗?
rest - 控制器在 MVC 应用程序上的 DDD 职责
我正在将一个应用程序重构为 DDD,到目前为止一切都很好,但我对一些责任以及解决它的最佳方法是什么表示怀疑。
该应用程序是呼叫中心代理使用的 Web 应用程序,具有 CRM 功能,后端是 REST API。
用例如下:代理打电话给客户,需要收集一些信息/提供促销等。在打电话给客户并与他交谈后,他需要为这次联系尝试填写一些信息,其中一些信息是组合的从数据库中填充数据的框,并将带有实体 ID 的 POST 发送到端点以注册它。
所以我们有一个端点contactAttempt,它接收数据、customerId、agentId、一些组合框信息(subjectId、reasonId、extraInfo1、extraInfo2),额外信息不调用它,只是为了简化。
该信息被反序列化为传递给应用程序服务的 DTO 对象,应用程序服务咨询相应的存储库以检查 id 是否有效并返回实体,如果找不到实体,它会引发控制器捕获并回答的异常带有消息的客户端。
如果所有实体都有效,则有一些域规则,例如是否是第一次与客户联系、发送欢迎电子邮件等。
我的疑问是从存储库中获取实体的这个步骤,它应该是这样的,或者我应该在控制器中获取它,如果我需要的所有东西都存在,那么我只需要应用的逻辑就传递给域服务业务规则?
- 上述方法的优缺点是什么?
- 还有其他方法吗?
- 在 MVC 的上下文中,Controller 的职责是什么?
c# - 如何为这个领域驱动的设计挑战建模?
在这里学习 DDD。
有两种用户 Member 和 Staff。会员可以拥有订阅列表,并且可以随时购买额外的订阅。员工用户还可以向成员添加订阅。当员工用户向会员系统添加订阅时,应记住谁添加了此订阅。
成员和员工用户处于完全不同的有界上下文中。他们拥有不同的权利集和可以参加的不同群体。所以我创建了一个成员聚合根,其中包含单独的有界上下文“成员”中的订阅列表。然后我在单独的有界上下文员工中创建了员工聚合根”。
当成员想要购买额外订阅时,这很容易,MemberService 只需将新订阅附加到成员,因为订阅是成员聚合和成员有界上下文的一部分。
但是,当员工用户想要向用户添加新订阅时,问题就开始了,因为不再是购买自己订阅的成员,而是将订阅分配给成员的员工。
我在这里看到了多种解决方案,但似乎没有一个是完全正确的。
- 将订阅实体添加到员工聚合。(尴尬,因为员工没有订阅)
- 当员工用户添加订阅时,通过成员聚合引发将成员订阅添加到成员的事件。(尴尬,因为添加订阅的不是会员)
- 直接从员工服务调用成员聚合(违反 DDD 原则)。
- 在有界上下文中为其自身移动订阅并使其成为聚合根。(可能是错误的,因为会员与他/她的订阅有密切的关系)
我在这里想念什么?
子问题:
是否允许跨多个有界上下文服务使用相同的 DTO?