当前位置: 首页 > 知识库问答 >
问题:

DDD-域服务实现:域或基础结构

严斌
2023-03-14

域内有一个接口“DetectPriorityInterface”。两个实现必须同时处于活动状态;一种“混合”必须实时地选择一种而不是另一种。

问题是:这些实现(两个实现)应该住在哪里:在域层还是基础结构层??

内部实现充满了业务规则,应该驻留在域层。外部实现是一个简单的调用,应该存在于基础结构中。

    null

客户端使用接口,因此,对于应用层,所有这些东西都是trasparent;接下来,我们将删除内部(或外部)和混合器,只使用一个实现。(所有这些背后的想法是为了了解谁的表现更好,这是一个A/BN测试)

我们内部的争论是:因为InternalDetector有一些只属于该检测器的域规则,它应该生活在基础结构层,因为它不是一个通用的域规则。我们中的一些人不同意这一点,因为在InternalDetector中我们只有业务规则,而在Infra层中我们看不到这一点。

有问题的正确方式应该是在域内添加内部,在域内添加外部。但似乎有点混乱..

把所有在一起的底层将更易读的开发人员...

我们没有在书中找到一些东西,因为通常你有一个域服务的单一实现....

共有1个答案

皮弘博
2023-03-14

简单的回答是,您应该在域层实现内部服务,在基础结构层实现外部服务,就像您在问题中所说的那样。这样,一切都会在它的位置上。

另一个需要考虑的重要问题是,决定调用哪个服务的代码也应该在域层中。从您的问题中我可以想象,您使用一些业务规则来决定使用哪个检测器。一个检测器在应用程序中实现,而另一个不是,这一事实只是系统的一个实现细节。实际上,您只是根据某个条件决定使用一组业务规则或另一组业务规则。这是一个商业决定。

DDD通常是关于困难的妥协。但是,当您正在寻找一个好的折衷方案时,我建议不要将域逻辑移到域层之外,也不要将域层的引用添加到其他层。

// Names in this code should be changed to something with business 
// meaning. For example `externalDetector` can be `governmentDetector` 
// and `internalDetector` can be `corporateDetector`.

// Declare a service interface in the domain layer
public interface DetectPriority {}


// Inject both detectors in the domain service.
// Your dependency injection code should inject here 
// an internal implementation and an external one, 
// implemented in the infrastructure layer.
// So your DI code knows about different implementations
// but the domain service doesn't.
// For the domain service it's just two implementations 
// of domain interface IDetector
IDetector _externalDetector;
IDetector _internalDetector;


// Implement the method of the domain service like this:
public Priority Detect() 
{
    if (weShouldUseExternalSetOfRules) 
    {
        return _externalDetector.Detect(); // this one is implemented in your infrastructure layer
    }
    else 
    {
        return _internalDetector.Detect(); // this one is implemented in your domain
    }
}

在这个解决方案中,您可以看到:

  1. 所有域逻辑(内部检测器和决定使用哪组规则的实现)都放在域层中。
  2. 我们的域没有对基础结构层的引用。域服务只引用IDetector接口,但此接口是在域层声明的。
  3. 域层中没有基础结构代码。在这种情况下,基础结构代码意味着类似于“使用查询字符串中的这组参数调用REST服务的GET方法”。显然,这段代码将在ExternalDetector实现中。

为了确保这是一个好方法,您可以使用著名的Eric Evans的书中的一个示例DDD应用程序来查看这个存储库。您可以找到在域层声明的服务接口和在基础结构层实现的服务本身。不幸的是,在此应用程序中没有在域层内部使用此服务接口的示例。但是它是在域层内部声明的,以使这种使用成为可能。

根据问题中的新信息,如果是关于a/B测试,那么选择检测器是应用级的决策。其他一切都保持不变。所以:

  • MixerDetector应位于应用程序层
  • DetectPriority接口-在域层中
  • 域层中的
  • internaldetecter
  • 基础结构层中的
  • ExternalDetector

而且检测器不需要“业务”名称,因为它们实际上是internaldetectorexternaldetector

 类似资料:
  • Bigtable是区域服务还是区域服务?我读到Bigtable是一个区域服务,然后我看到Bigtable的区域复制现在已经在GA中了。Bigtable和Datastore的区别是什么,我看到Bigtable是一种IaaS,数据存储是完全管理的,谁能解释一下这两者之间的区别,有点混乱。谢谢

  • 3.4 ABP领域层 - 领域服务 3.4.1 简介 领域服务(或者服务,在DDD模式中)是被用来执行领域操作或者业务规则的。Eric Evans 在他的DDD书中这样说过:一个好的Service应该有以下三个特征: 与领域概念相关的操作不是Entity或Value Object 的一个自然部分; 接口是根据领域模型的其它元素定义的; 操作是无状态的。 领域服务和Application Servi

  • 不过,当我发现有必要的时候,我开始稍微尝试应用概念。我发现仍然有许多我不能甚至不考虑应用到我的应用程序中,其中一些是:适配器、命令(CQR?)、事件… 除此之外,我还有点纠结于与六角形建筑有关的东西。我试图应用外部行为应该依赖于内部的定义,所以基础结构层->应用程序层->领域层 在本例中,我将应用程序层中的服务定义为以下LoginService示例:

  • 本文向大家介绍spring Cloud微服务跨域实现步骤,包括了spring Cloud微服务跨域实现步骤的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了spring Cloud微服务跨域实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 第一步:在gateway网关的配置文件中加上下面这些: 第二步:写一个配置类解析上面的配置文

  • 本文向大家介绍java web服务器实现跨域访问,包括了java web服务器实现跨域访问的使用技巧和注意事项,需要的朋友参考一下 一、CORS概述 跨源资源共享标准通过新增一系列 HTTP 头,让服务器能声明那些来源可以通过浏览器访问该服务器上的各类资源(包括CSS、图片、JavaScript 脚本以及其它类资源)。另外,对那些会对服务器数据造成破坏性影响的 HTTP 请求方法(特别是 GET

  • Config配置类 StaticCache静态缓存类 Route路由类 Controller控制器类 View视图类 Request请求类 Response响应类 Event事件类 Listener监听类 Subscriber多事件监听 EventDispatcher事件调度