Domain driven design 在绿地工程中考虑轴突

Domain driven design 在绿地工程中考虑轴突,domain-driven-design,axon,Domain Driven Design,Axon,几个月后我将开始一个绿地项目 该项目将包含大量的业务逻辑,分布在几个子域中。是的,我们将使用领域驱动设计的原则。 技术将包括Spring、Spring引导和Hibernatestack 我正在研究一些Java LIB,以涵盖基础设施方面的内容,如: 域事件发布 事件存储 事件重复数据消除 用户端的重排序器 投影 可靠发布 可靠的交付和重新交付 我遇到了Axon框架。我已经听说了,不知道细节。所以我读了一些博客文章,一些文档,并在Youtube上观看了一些广播 它看起来很有前途,我正在考虑使

几个月后我将开始一个绿地项目
该项目将包含大量的业务逻辑,分布在几个
子域中。是的,我们将使用
领域驱动设计的原则。
技术将包括
Spring、Spring引导和Hibernate
stack

我正在研究一些Java LIB,以涵盖基础设施方面的内容,如:

  • 域事件发布
  • 事件存储
  • 事件重复数据消除
  • 用户端的重排序器
  • 投影
  • 可靠发布
  • 可靠的交付和重新交付
我遇到了
Axon框架
。我已经听说了,不知道细节。所以我读了一些博客文章,一些文档,并在Youtube上观看了一些广播

它看起来很有前途,我正在考虑使用它,因为我不想在基础设施方面一次又一次地重复使用它。
所以我想找个人来回答和澄清我的问题:

命令处理 Axon使用
commandHandler
void
方法。是否可以让它们返回一个值(例如生成的业务id)或对象,以用于有关业务操作的通知目的
对于我来说,该方法将被此方法阻塞I/O不是问题


本地与远程域事件发布 我想明确区分
本地
远程
域事件。
Local domain
事件应仅对本地子域可见和使用。是否可以配置事件消耗同步和/或异步? 我的本地域事件可以是“fat”。他们被允许携带更多的数据,因为它不会跨越域边界

远程域事件
将为“精简”,因此只有远程域所需的最小数据。这种类型的操作事件需要始终是异步的

是否可以在域边缘将本地(fat)域事件转换为远程(精简)域事件?所谓“边缘”,我指的是基础设施方面。 这样,域模型就不需要知道本地和远程域事件之间的区别


同步地 我的应用程序将包括1个(可能2个)
核心域
几个子域
。某些域包含大量业务逻辑,需要
CQRS

其他领域将更“粗糙”的风格。 有可能同步执行
CQRS
吗?
在增加异步处理等技术复杂性之前,我想先从这一点开始。这可能与轴突有关

这也意味着域事件将存储在事件存储中,而不使用
事件源


是否可以在不使用事件源的情况下使用Axon的
事件存储?
同样对于投影的东西,我只想投影域事件来构建我的读取模型


模块整体 我们将使用一个
模块化的整块体

如今,所有的
微服务都不是很时髦。尽管如此,我相信有一个整体,其中每个域都是完全分离的(应用程序代码和数据库模式),操作将以最终的一致性处理,域事件包含必要的数据。
以后,如果需要,迁移到
微服务体系结构将更容易


Axon是一个适合模块化整体式架构的框架吗?有什么需要考虑的吗


完全分离的域模型(持久性不可知) 域模型将与数据模型完全分离。 我们需要一个存储库来读取数据模型(使用
Hibernate
),并在需要加载时使用
数据映射器来创建聚合。
另一种方法也是需要的,需要将聚合转换并保存到数据模型中(使用数据映射器)
此外,聚合的域事件需要存储到事件存储中,并发布到本地或远程事件处理程序

这会产生一些后果:

  • 我们需要完全控制与一个或多个DAO(Spring数据存储库)通信的存储库实现,以便从Hibernate实体中提取必要的数据,并用它构建一个聚合。毕竟,一个聚合可以在2个甚至3个关系表中建模

  • 我们在域模型中不需要任何Hibernate注释

这种方法对轴突有可能吗?我只看到使用直接JPA(域模型将1到1映射到实体)或事件源的示例。
这种方法对我们来说真的是一个破坏者,一个分离的域模型提供了比直接映射到数据实体更多的可能性

下面是我想要实现的一个示例:

在某些域模型包中聚合(不含JPA):

public class ScoringResultAggregate {
  // members, constructor, operation omitted for brevity
}
某些基础架构包中的Hibernate实体:

属于域模型的存储库接口:

public interface ScoringResultRepository {
  void save(ScoringResultAggregate scoringResultAggregate);

  ScoringResultAggregate findByApplicationNumber(ApplicationNumber applicationNumber);
}
实现存储库接口的适配器;负责将聚合从/映射到数据(JPA)模型:


轴突服务器
Axon服务器
看起来很有前途。尽管如此,它是否仅适用于
事件源
? 它是否可以与存储聚合(状态持久化)并在Axon服务器中持久化域事件的Sql DB一起使用




很多问题。希望有Axon经验的人能帮助我:-)

我希望我能回答其中一些问题,但我在使用Axon方面也不是很有经验:

从命令处理程序返回值-是的,这是可能的。我们有一个例子,返回生成的聚合id(我不能100%确定这个答案)

本地与远程doma
public interface ScoringResultRepository {
  void save(ScoringResultAggregate scoringResultAggregate);

  ScoringResultAggregate findByApplicationNumber(ApplicationNumber applicationNumber);
}
class ScoringResultAdapterRepository implements ScoringResultRepository {
  private ScoringResultJpaRepository scoringResultJpaRepository;

  ScoringResultJPARepository(ScoringResultJpaRepository scoringResultJpaRepository) {
    this.scoringResultJpaRepository= scoringResultJpaRepository;

  public void save(ScoringResultAggregate scoringResultAggregate) {
    // converts aggregate to ScoringResultEntity and saves the state into DB
  }

  public ScoringResultAggregate findByApplicationNumber(ApplicationNumber applicationNumber) {
    // loads an ScoringResultEntity from DB and converts it into an aggregate
  }
}