小编Paw*_*zyk的帖子

使用事件采购时在何处验证业务规则

我实现了事件源实体(在域驱动设计中称为聚合).创建富域模型是一种很好的做法.域驱动设计(DDD)建议尽可能将所有与业务相关的事物放入核心实体和价值对象中.

但是,将此类方法与事件采购结合使用时存在一个问题.与事件源系统中的传统方法相比,首先存储事件,然后在构建实体以执行某些方法时应用所有事件.

基于此,最大的问题是在哪里放置业务逻辑.通常,我想有一个方法,如:

public void addNewAppointment(...)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望该方法可以确保不违反任何业务规则.如果是这种情况,则会抛出异常.

但是在使用事件采购时,我必须创建一个事件:

Event event = new AppointmentAddedEvent(...);
event store.save(event);
Run Code Online (Sandbox Code Playgroud)

现在,我在存储事件之前探索了两种检查业务规则的方法.

首先,检查应用程序层中的业务规则.DDD中的应用程序层是委托层.实际上,它应该不包含业务逻辑.它应该只委托获取核心实体,调用方法和保存的东西.在此示例中,将违反此规则:

List<Event> events = store.getEventsForConference(id);

// all events are applied to create the conference entity
Conference conf = factory.build(events); 

if(conf.getState() == CANCELED) {
    throw new ConferenceClosed()
}

Event event = new AppointmentAddedEvent(...);
event store.save(event);
Run Code Online (Sandbox Code Playgroud)

显然,添加到已取消会议的约会的业务规则不应该泄露到非核心组件中.

我知道的第二种方法是将命令的处理方法添加到核心实体:

class Conference {
// ...

    public List<Event> process(AddAppointmentCommand command) {
        if(this.state == CANCELED) {
            throw new ConferenceClosed()
        }

        return Array.asList(new AppointmentAddedEvent(...));
    }

// ...
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,好处是业务规则是核心实体的一部分.但存在违反分离关注原则的情况.现在,该实体负责创建存储在事件存储中的事件.除此之外,实体负责创建事件感觉很奇怪.我可以争论为什么实体可以处理事件.但是,用于存储而不是用于自然发布的域事件的创建感觉是错误的.

你有没有人遇到过类似的问题?你是如何解决这些问题的?

现在,我将使用应用程序服务解决方案中的业务规则.它仍然是一个地方,但它违反了一些DDD原则. …

domain-driven-design cqrs event-sourcing

7
推荐指数
1
解决办法
448
查看次数

为什么要使用MockWebServer而不是WireMock?

每当我需要模拟一些http请求时,我的第一个选择就是WireMock(我认为这实际上是标准的),但是今天我发现了一些替代工具-MockWebServer。

WireMockMockWebServer的优缺点是什么?

java mocking mockwebserver wiremock

5
推荐指数
1
解决办法
2486
查看次数