小编Jou*_*ist的帖子

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

我实现了事件源实体(在域驱动设计中称为聚合).创建富域模型是一种很好的做法.域驱动设计(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
查看次数

如何在faunadb中按多个条件查询?

我试图提高我对 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)

我想通过不同的属性以灵活的方式进行查询,例如:

  • data.attributes.amenities.camping > 5
  • data.attributes.amenities.camping > 5 AND data.attributes.amenities.hiking > 6
  • data.attributes.amenities.camping < 6 AND data.attributes.amenities.culture > 6 AND 徒步旅行 > 5 AND ...

我创建了一个包含所有属性的索引,但我不知道如何在包含多个术语的索引中进行更大的等于过滤。

我的回退是为每个属性创建一个索引并使用 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)

faunadb

5
推荐指数
2
解决办法
2556
查看次数

JAX-RS,路径参数不起作用

我尝试通过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}")它也不起作用.似乎有一个参数,但它没有任何理由是空的.也许有人可以帮我解决问题.

亲切的问候

java rest jax-rs path-parameter

3
推荐指数
2
解决办法
2342
查看次数