关于有界上下文和它们之间的交互的混淆 [英] Confusion regarding bounded contexts and interaction between them

查看:21
本文介绍了关于有界上下文和它们之间的交互的混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读了 Eric Evan 关于域驱动设计的书之后,我正在尝试实现我的第一个域驱动应用程序.我对如何解决这个问题有些困惑.

I'm trying to implement my first domain driven application, after going through Eric Evan's book on Domain-Driven Design. I'm a bit confused on how to go about this.

在我的应用程序中,用户可以购买一项服务,让他们在 Youtube 上发布的视频获得一定数量的观看次数,这由我的应用程序中观看这些视频的其他用户完成(基本上是许多 YouTube推广应用已经可用,可供学习).

In my application, a user can purchase a service for getting them certain number of views on a video they post in Youtube, which is fulfilled by the other users of my app who watch those videos(Basically a replica of the many youtube promoter apps already available, for learning).

假设服务在应用中表示为名为 WatchTime 聚合的实体.WatchTime 实体包含一些信息,例如购买此服务的用户的 ID、购买的最大观看次数、已完成的观看次数以及观看一次视频的人获得的积分.

Say the service is represented in the app as an entity called WatchTime aggregate. The WatchTime entity contains some information like the id of user who purchased this service, the max number of views purchased, number of views already fulfilled, and points earned by someone who views the video once.

我决定使用 3 个有界上下文,一个用于身份验证,一个用于处理观看时间,例如添加或删除它们,另一个用于管理用户及其数据.现在用户有他的个人信息和他在使用应用程序时收集的一些积分.

I decided to go with 3 bounded contexts, one for authentication, one for handling the watchtimes, like adding or removing them, and one for managing users and their data. Now the user has his personal info and some points that he collected while using the application.

起初我认为所有用户数据和相关操作都在第三个上下文中,例如为用户添加更多积分或减少他的积分,但是在制作模型时,我意识到如果观看时间购买服务将在第二个服务中,然后每次购买 WatchTime 时,它​​都必须与第三个服务进行通信,以告诉那里的服务减少该购买的积分.把它们放在两个不同的地方是没有意义的.

At first I was thinking that all the user data and related actions be in the 3rd context, like adding more points to a user and or reducing his points, but then while making the model, I realized that that if the watch time purchasing service is going to be in the second one, then its going to have to communicate to the third one every time a WatchTime is purchased to tell a service there to reduce points for that purchase. It wouldn't make sense to keep them in two different ones.

所以相反,我想到的是在第二个有界上下文中有一个用户模型,但只有点数和该用户购买的 WatchTimes,所以现在它不必在第三个上下文中调用某些东西.

So instead what I'm thinking of is have a model of the user in the 2nd bounded context, but with only points and the WatchTimes that this user purchased, so now it doesnt have to call something on the 3rd context.

我的问题是如何正确地将事物分离到上下文中?是基于模型,还是应该基于功能,并且所有与这些功能相关的模型都将处于相同的上下文中?

My question is how to properly seperate things into contexts? Is it like based on the models, or should it be based on the functionality, and all models related to those functionality are going to be in the same context?

还有一点,如何保证同一个实体的所有对象都具有相同的值并正确地持久化到数据库中?一次是否应该只存在一个代表特定实体的对象,该对象将在函数结束时被持久化和处理?因为我在想,如果代表同一实体的两个对象同时存在,则有可能两者具有不同的值或更改为不同的值.

And another thing, how to ensure that all the objects of the same entity have the same value and properly persisted in the database? Should only one object representing a particular entity be present at a time, which will be persisted and disposed by the end of a function? Because I was thinking that if two objects representing the same entity be present at the same time, there's a possibility of both having different values or changing to different values.

如果我听起来像是在胡言乱语,请告诉我是否需要更清楚.谢谢.

If i sound like im rambling, please let me know if I have to be more clear. Thanks.

推荐答案

有界上下文基本上定义了通用语言(以及模型)相同的功能区域.在不同的有界上下文中,用户"可能意味着不同的东西:在用户配置文件"中上下文,您可能有他们的电子邮件地址,但在查看时间"中上下文,您只需授予积分并购买收视率即可.

Bounded contexts basically define areas of functionality where the ubiquitous language (and thus the model) are the same. In different bounded contexts, "user" can mean different things: in a "user profile" context, you might have their email address but in the "viewing time" context, you'd just have the points granted and viewership purchased.

重新另一件事",一般来说,您需要保持聚合高度一致,并且只有在更新识别成功的每个先前更新(包括从数据存储区读取后成功的任何更新)时才允许更新成功.这就是单写入器原则.

Re "another thing", in general you need to keep an aggregate strongly consistent and only allow an update to succeed if the update is cognizant of every prior update which succeeded, including any updates which succeeded after a read from the datastore. This is the single-writer principle.

有几种方法可以实现这一点.首先,您可以使用乐观并发控制并为每个聚合存储一个版本号.然后,仅当版本没有更改时才更新数据库中的聚合;否则,您将尝试针对新版本的聚合进行操作(执行所有验证等).这需要数据库中的一些支持来对版本和更新(例如事务)进行原子检查.

There are a couple of ways to accomplish this. First, you can use optimistic concurrency control and store a version number with each aggregate. You then update the aggregate in the DB only if the version hasn't changed; otherwise you attempt the operation (performing all the validations etc.) against the new version of the aggregate. This requires some support in the DB for an atomic check of the version and update (e.g. a transaction).

另一种方法(我个人的偏好)是认识到 DDD 聚合对计算的参与者模型具有高度的机械同情(例如,两者都是强一致性单元).有一些参与者模型的实现(例如 Microsoft Orleans、Akka Cluster Sharding)允许在给定时间最多由一个参与者表示聚合(即使有许多服务器的集群).

An alternative approach (my personal preference) is to recognize that a DDD aggregate has a high level of mechanical sympathy to the actor model of computation (e.g. both are units of strong consistency). There are implementations of the actor model (e.g. Microsoft Orleans, Akka Cluster Sharding) which allow an aggregate to be represented by at most one actor at a given time (even if there is a cluster of many servers).

这篇关于关于有界上下文和它们之间的交互的混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆