Domain driven design 领域设计中的反应式编程

Domain driven design 领域设计中的反应式编程,domain-driven-design,reactive-programming,Domain Driven Design,Reactive Programming,我习惯于开发创建“域实体”的软件——这些实体“依赖”域内的其他实体 假设我有这个接口 package domain; import domain.beans.City; public interface CitiesRepository { City get(String cityName); } 正如您所看到的,我返回的城市又是一个域对象。此CitiesRepository的实现可以在域外找到,并且可以依赖于数据库、http客户端、缓存的装饰器等 我现在正在使

我习惯于开发创建“域实体”的软件——这些实体“依赖”域内的其他实体

假设我有这个接口

package domain;

import domain.beans.City;

public interface CitiesRepository {  
  City get(String cityName);          
}
正如您所看到的,我返回的
城市
又是一个域对象。此
CitiesRepository
的实现可以在域外找到,并且可以依赖于数据库、http客户端、缓存的装饰器等

我现在正在使用一个反应式框架——vert.x——我试图理解如何继续使用这种模型。我不想要特定于vert.x的答案,只想了解是否有任何模式/最佳实践来理解如何实现这一点

在反应式编程中,几乎从来没有返回值,但总会有一些回调/处理程序在事件发生后使用它。我应该将我的接口重写为“反应式”吗

包域;
导入domain.beans.City;
公共接口CitiesRepository{
void get(字符串cityName,DomainHandler cityHandler);
}
仅提供这个示例就让我在考虑实现时感到有些头痛,因为我必须处理“反应式框架”的处理程序来“填充”我的域处理程序

在使用反应式模型时,我是否应该停止考虑这种设计?我应该选择可观察/承诺的方法吗


在我参与的反应式系统中,有一个事件处理程序将使用存储库,任何提示都将非常有用:

public void SomeEventHandler : IHandle<SomeEvent> {
public SomeEventHandler(CityRepository repo) {}
}
在应用程序的CompositionRoot中,将注册处理程序,以通过接收/生成事件的任何消息传递总线/反应流等来处理事件


因此,我不希望让存储库成为反应式的,而是添加一个事件处理程序来使用它。

使用反应式设计,您添加了一层API调用方式的间接定向,并指定除了原始的香草规范之外的其他层。原因是,在异步设计中,如何调用东西非常重要,而且并不总是一刀切,因此最好不要过早做出重大决策,或者将“它是什么/做什么”与“它是如何做的”绑定在一起

有三种使事情异步化的常用工具:

  • 未来/承诺
  • 回拨
  • 消息传递
就整个设计而言,Future/promise是三者中最具约束力的,在实现方面通常是最棘手的,您需要采取很多措施来防止设计中出现ABA错误,并确保Future仍在运行,但没有人需要结果。是的,它们抽象出并发性,是一元的等等,但是当你添加第一个的时候,它们就把你当作人质,而且它们很难摆脱

回调是单个进程中速度最快的,但要使它们与基于角色的系统或跨线路工作,您不可避免地要使用消息。此外,当您需要第一个状态机时,您需要立即使用事件队列和消息。因此,要想证明未来最安全,最安全的方法就是只发送消息。就这两种机制的简单程度而言,在消息和回调之间移动非常简单(如果可能的话)

按键查找城市的协议可以是这样的:

protocol Requests
message GetCityRequest(name): Requests

protocol Responses
message GetCityResponse(cityMaybe): Responses
但我非常了解这个主题,我想说的是,投资于通用形式的“状态复制模式”,并将其用于简单的静态查找和动态订阅。这并不难,它将是您的主要工作马,为您的大多数系统需求

public void When(SomeEvent event) {
    var city = _cityRepository.Get(event.CityName);
// do something with city
}
protocol Requests
message GetCityRequest(name): Requests

protocol Responses
message GetCityResponse(cityMaybe): Responses