Domain driven design 如何在CQR中处理摘要/报告?
我在做一个酒店预订项目。一项新功能要求客户可以对酒店发表评论。每个注释都有一个评级(0-->5)。在“搜索酒店”页面上,每个酒店都显示其平均评级 添加评论非常简单,可以发布一个CommentAddedEvent:Domain driven design 如何在CQR中处理摘要/报告?,domain-driven-design,cqrs,idempotent,Domain Driven Design,Cqrs,Idempotent,我在做一个酒店预订项目。一项新功能要求客户可以对酒店发表评论。每个注释都有一个评级(0-->5)。在“搜索酒店”页面上,每个酒店都显示其平均评级 添加评论非常简单,可以发布一个CommentAddedEvent: class CommentAddedEvent { private String hotelId; private double rating; //other attributes omitted } 在查询端,将在此事件上保留注释行: create t
class CommentAddedEvent {
private String hotelId;
private double rating;
//other attributes omitted
}
在查询端,将在此事件上保留注释行:
create table t_comment {
hotel_id number,
rating number(2,1)
}
但我们在如何显示酒店的平均评级方面进展缓慢。以下是我们的潜在解决方案:
a)数据库集成
在搜索酒店查询端,使用sql函数获取平均值:
select h.id, h.name,....,select avg(c.rating) from t_commentc , t_hotel
where.... group by c.hotel_id.....
这看起来很容易,但我们认为这会在测试中引入更多的工作,并可能会导致一些性能问题
b)EventHandler计算平均值
添加订阅CommentAddEvent的事件处理程序并计算平均值:
public void on(CommentAddedEvent event) {
Hotel hotel = ....
double total = hotel.rating * hotel.comments;
double average = (total + event.rating)/(hotel.comments + 1)
//update hotel
}
这个测试很容易,但这个解决方案似乎不是幂等的。当某个事件失败时,事件处理程序可能会处理重复事件
c)计划任务
添加计划任务,总结每个酒店的评论。但这是低效的,因为自上一个任务以来,一些酒店没有评论
d)与事件处理程序混合的计划任务
使用事件处理程序标记自上次任务以来发生的事件:
public void on(CommentAddedEvent event) {
int count = uncalculatedCommentsOnHotel(...);
count++;
//update count
}
并根据计数大于零的酒店安排汇总任务
解D是幂等的,似乎更有效。是否存在我们制造的缺陷或任何其他解决方案?我会选择实现一个计算平均值的事件处理程序(选项b)。您有一些克服幂等性问题的策略
public void on(CommentAddedEvent event)
{
Hotel hotel = ....
if (hotel.CommentIds.Contains(event.CommentId))
return; // comment has already been processed
double total = hotel.rating * hotel.comments;
double average = (total + event.rating)/(hotel.comments + 1)
hotel.CommentIds.Add(event.CommentId);
//update hotel
}
- 吉米·博加德
- 乔纳森·奥利弗