dtn43447 2019-07-14 06:31
浏览 75

DDD在相同的有界上下文中聚合边界决策

Application is an offers wall written on PHP/Laravel/Doctrine, where we have a wall created by application user, we have offers what we need to show on the wall, and we have some end-user identifier which is not app user and it does not have own table in system, it's just a string identifier. So I divide app to accounts BC (where we have app user related things), offers BC and walls BC. In this example, we going to work with walls BC.

I have such a DB structure (simplified):

wall:

  • id: int
  • owner_id: int (User id from another BC)
  • name: string

wall_devices:

  • id: int
  • name: string
  • human_name: string

wall_user_device:

  • id: int
  • device_id: int (relation to wall_device)
  • end_user_id: string
  • wall_id: int (relation to wall)

wall_banned_users:

  • id: int
  • wall_id: int (relation to wall)
  • end_user_id: string

wall_points:

  • id: int
  • offer: id (offer id from another BC)
  • wall_id: int (relation to wall)
  • end_user_id: string

So at first glance, it looks like wall is an Aggregate Root and wall id is an aggregate identifier, right?

Let's provide an example flow, we need to open a wall for some end user (remember it's just a string), so we have a request with wall.id and end_user_id data. Steps:

  1. using WallRepository we getting the wall aggregate
  2. now we need to get all offers we want to show, but to do so I need to get devices selected by end_user_id previously if they exist. In such a case we need to query DB (note I'm telling query DB instead of using repository b-z in DDD repository should work only with the whole aggregate) to wall_user_device table as it's not possible to get it as a part of wall aggregate, right?

One more example, end user complete some offer so we need to check if wall_points exists for end-user and if so change the point status, so again we have a request with wall.id and end_user_id data:

  1. using WallRepository we getting the wall aggregate
  2. now we need to get wall_points instance and update if exists. So here again we need to query DB as it's not possible to get with wall aggregate.

So at this point, I have a feeling that wall aggregate is not designed correctly as the only thing what he doing is manipulating only a wall table, and to get all other data we need to make additional queries with a combination of wall_id/end_user_id.

So looks like more logically is to somehow create aggregate around the wall_id-end_user_id combination as an aggregate root entity identifier and to get all the data from the repository as a single aggregate. But I guess it requires creating some workaround to combine few doctrine entities to a single DDD entity if it's even possible

Or another possible solution is to still use wall_id as an identifier and just join all the data only by wall_id and filter the data later on by end_user_id, but in such case, we going to query/manipulate with the huge amount of data as the wall can have tons of end user and this will have a bad effect on app performance.

Maybe someone faced a similar issue and can help me with making a correct architectural decision here?

Also, I want to note that it's an existing/legacy app with the already pretty big database and this part of the app working, so it's not preferred to change DB structure.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 keil里为什么main.c定义的函数在it.c调用不了
    • ¥50 切换TabTip键盘的输入法
    • ¥15 可否在不同线程中调用封装数据库操作的类
    • ¥15 微带串馈天线阵列每个阵元宽度计算
    • ¥15 keil的map文件中Image component sizes各项意思
    • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
    • ¥15 划分vlan后,链路不通了?
    • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
    • ¥15 Vue3 大型图片数据拖动排序
    • ¥15 Centos / PETGEM