我实现了事件源实体(在域驱动设计中称为聚合).创建富域模型是一种很好的做法.域驱动设计(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原则. …
我试图提高我对 FaunaDB 的理解。
我有一个包含以下记录的集合:
{
"ref": Ref(Collection("regions"), "261442015390073344"),
"ts": 1587576285055000,
"data": {
"name": "italy",
"attributes": {
"amenities": {
"camping": 1,
"swimming": 7,
"hiking": 3,
"culture": 7,
"nightlife": 10,
"budget": 6
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想通过不同的属性以灵活的方式进行查询,例如:
我创建了一个包含所有属性的索引,但我不知道如何在包含多个术语的索引中进行更大的等于过滤。
我的回退是为每个属性创建一个索引并使用 Intersection 来获取我想要检查的所有子查询中的记录,但这感觉有点不对:
查询:budget >= 6 AND camping >=8 将是:
Index:
{
name: "all_regions_by_all_attributes",
unique: false,
serialized: true,
source: "regions",
terms: …Run Code Online (Sandbox Code Playgroud) 我尝试通过GET将参数传递给REST方法.
@GET
@Path("{id}")
public Response getUser(@PathParam("id") String id) {
Query qry = em.createQuery("from User c WHERE id = :user_id");
qry.setParameter("user_id", id);
List<User> results = qry.getResultList();
if(results.size() > 0) {
return Response.ok(results.get(0),MediaType.APPLICATION_JSON_TYPE).build();
} else {
return Response.serverError().status(Response.Status.NOT_FOUND).build();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我通过Rest Client调用它:
client = ClientBuilder.newClient();
Response response = client.target(TestPortProvider.generateURL("/user")+"/abc").request().get(Response.class);
Run Code Online (Sandbox Code Playgroud)
然后调用该方法,但参数为空.如果我"abc"从GET url中删除该方法,则不会调用该方法.此外,如果我删除@Path("{id}")它也不起作用.似乎有一个参数,但它没有任何理由是空的.也许有人可以帮我解决问题.
亲切的问候