gpt4 book ai didi

architecture - 如何在 DDD/CQRS/EventSourced 项目中建模投票/点赞系统?

转载 作者:行者123 更新时间:2023-12-03 09:27:14 26 4
gpt4 key购买 nike

这是我的域的简要说明:

我的文章基本上和任何文章一样(标题、摘要和正文)。

我需要允许对我的文章进行投票,投票将由匿名用户投票(无需注册,但 session 会存储投票,请不要关注这一点)。

在这个域中,文章是我的聚合根。

我找不到满足以下要求的选票建模方法:

投票可以是我喜欢或不喜欢,它应该是可变的(它可以随着时间的推移而改变甚至取消)

具有关联 session 的访客用户只能为每篇文章投一票。

那么,Vote 是否应该单独聚合?

就像是

Class Vote {
public function cast(ArticleId id, GuestSessionToken token, VoteValue value);
}

但在这种情况下,我应该如何检查唯一性?使用最终一致性(这似乎没问题,因为我没有一些重复,因为它们很少见)。

因为如果我将投票方法添加到我的文章聚合中,我将不得不为每篇投票重播历史,这听起来很慢(考虑到我每篇文章可以有 10 万票)。

我知道在设计 DDD 方式时不应该考虑性能和优化,但这里是我在实现任何东西之前需要解决的一个特定问题。

你们中有人做过类似的事情吗?

最佳答案

投票本身就是一个聚合根。如果我们考虑关联“一篇文章有​​很多票”,那么我们正在应用一种关系方法,这使我们倾向于 DDD 社区同意的如此批评的大聚合方法。相反,我们希望关注行为。我们已经知道,文章不会持有投票集合。由于投票需要自己的生命周期,因此它将拥有自己的全局身份和自己的存储库。一篇文章是由用户投票的,这是给我们的领域模型提供语义的一种很好的方法,所以玩领域专家语义我们可以说“一篇文章是由用户投票的”

anArticle.votedBy(aReader);

请记住,用户在此有界上下文中扮演读者的角色。 votedBy 方法是一个工厂方法,它处于创建投票的位置。它的实现将是:
Article.votedBy(aReader) {
return new Vote(this, aReader);
}

永远记住,最后一个投票将具有文章和读者的概念标识符,促进断开连接的模型,而不是保存对其他聚合根的实际引用。所以域服务将是阅读器本身。假设您对休息界面进行建模
RestInterface.voteArticle(articleId) {
reader = new Reader(articleRepository);
reader.vote(articleId);
}

Reader.vote(anArticleId) {
article = articleRepository.get(anArticleId);
vote = article.votedBy(this);
voteRepository.add(vote);
}

您应该通过在数据库级别放置一个组合唯一约束来检查唯一性(确保用户只对一篇文章投票一次)。这是检查它的侵入性最少的方法,否则您应该添加另一个可以调节投票的域模型。也许当创建不同的投票业务规则时,这个新对象更有意义,但为了确保读者只对一篇文章进行一次投票就足够了,我认为最简单的解决方案(即放置 DB 约束)。
DDD 是一个学习过程,当我们学习有关领域的新事物时,我们意识到用户可以点击文章上的“喜欢”或“不喜欢”按钮,因此我们考虑重新分解我们到目前为止所做的事情:
Article.likedBy(aReader) {
return Vote.positiveByOn(aReader, this);
}

Article.dislikedBy(aReader) {
return Vote.negativeByOn(aReader, this);
}

其中两个实现是:
class Vote {

readerId
articleId
typeId

Vote(aReaderId, anArticleId, aType) {
readerId = aReaderId
articleId = anArticleId
type = aType
}

public Enum VoteType { POSITIVE, NEGATIVE }

Vote static positiveByOn(aReader, anArticle) {
return new Vote(aReader.id, anArticle.id, POSITIVE);
}

Vote static negativeByOn(aReader, anArticle) {
return new Vote(aReader.id, anArticle.id, NEGATIVE);
}
}

此外,由于文章 AR 上的 likeBy/dislikedBy 工厂方法正在创建投票,您可以设置一个约束,说明一篇文章不能被投票超过 N 次或任何其他业务场景。

希望能帮助到你,

塞巴斯蒂安。

关于architecture - 如何在 DDD/CQRS/EventSourced 项目中建模投票/点赞系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27058509/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com