架构域模型和视图模型 [英] Architecture Domain Model and View Model

查看:38
本文介绍了架构域模型和视图模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 Spring Boot 和领域驱动设计来构建应用程序.我有一个关于域模型(与表 DB 的字段匹配)和视图模型(响应 API)的问题.

领域模型:

例如:班级名称

@Getter@NoArgsConstructor@AllArgsConstructor班级名称 {字符串值;}

class 产品

@Getter@NoArgsConstructor@AllArgsConstructor类产品{姓名名称;}

视图模型:

@Data@NoArgsConstructor@AllArgsConstructor类产品视图{//int prodId;字符串产品名称;}

按类别产品选择数据数据库,按类别ProductView选择响应API的构建器.当从 DomainModel 转换为 ViewModel 或反之时,我为此在 ProductView 中编写了静态方法.它会变成:

@Data@NoArgsConstructor@AllArgsConstructor类产品视图{//int prodId;字符串产品名称;公共静态产品视图(产品产品){String productName = prod.getName().getValue();返回新的产品视图(产品名称)}}

效果很好,但是当数据变得更多时.我认为需要将 CommonConvertDomainModel 转换为 ViewModel,反之亦然.

我有一个使用 Mapstruct 库的解决方案.但 Mapstruct 仅支持转换字段相同类型(字符串与字符串,ex).编写 CommonConvert 的最佳解决方案是什么?

解决方案

我的建议:不要查询领域模型并将其转换为查看模型以供阅读.>

域模型类(例如聚合)用于表示业务数据和行为,目的是在创建或更改此类业务实体时遵守业务不变量.

为了从持久数据构建视图模型,您可以 - 在我看来您应该 - 绕过域模型.您可以根据需要安全地从数据库中读取数据,而无需通过域存储库.

这没关系,因为您不能仅通过读取数据来违反业务规则.要写入数据,请通过域存储库和聚合.

在您的情况下,您当然可以通过设计这些类来完全满足您的查看要求,从而使用使用 JPA 注释的视图模型实体.请记住,视图模型通常与域模型无关,因为它们可能只需要数据的一个子集或从不同聚合中聚合数据.

另一个问题是,如果您需要查询许多对象进行查看,如果您通过存储库查询完整的域聚合,可能会很快导致性能问题.因为这样的聚合总是从它的子实体和值对象加载所有数据,以允许使用所有不变量执行业务逻辑,你最终会执行大量昂贵的查询,这些查询适合加载单个聚合,但不是一次加载很多.

因此,通过仅查询您需要查看的内容,您还可以解决此类性能问题.

在遵循 DDD 时,您通常只应在业务交易中创建或更改一个聚合.所以领域模型不适合查询优化,而是用于在编写业务数据时保持业务不变量的完整性.

查看模型和相应的查询针对读取和收集所需的所有数据进行了优化.

I am trying to build application by spring boot and Domain Driven Design. I have a problem about Domain model (match with fields of table DB) and View Model (response API).

Domain Model:

EX: class Name

@Getter 
@NoArgsConstructor
@AllArgsConstructor
class Name {
  String value;
}

class Product

@Getter 
@NoArgsConstructor
@AllArgsConstructor
class Product{
  Name name;
}

ViewModel:

@Data
@NoArgsConstructor
@AllArgsConstructor
class ProductView {
  //int prodId;
  String prodName;
}

Select data DB by class Product, builder to Response API by class ProductView. When that convert from DomainModel to ViewModel or vice versa, I written static method in ProductView for that. It will become:

@Data
@NoArgsConstructor
@AllArgsConstructor
class ProductView {
  //int prodId;
  String prodName;
  public static ProductView of(Product prod) {
    String productName = prod.getName().getValue();
    return new ProductView(productName)
  }
}

It works well, but when the data becomes more. I think need that as CommonConvert from DomainModel to ViewModel and vice versa.

I have a solution use Mapstruct library. But Mapstruct only support to convert field same type(String with String, ex). What is the best solution for writting CommonConvert?

解决方案

My advice: do not query domain models and translate them to view models for reading.

Domain model classes (e.g. aggregates) are used to represent business data and behaviour with the to purpose to adhere to business invariants when creating or changing such business entities.

For building your view models from your persistent data you can - and in my opinion you should - bypass the domain model. You can safely read the data from your database as you need it without going through domain repositories.

This is okay because you can't violate business rules by just reading data. For writing data go through domain repositories and aggregates.

In your case you can of course use view model entities using JPA annotations by designing those classes to exactly fit your viewing requirements. Keep in mind that view models often don't correlate to domain models as they might only need a subset of the data or aggregate data from different aggregates.

Another catch is that if you need to query many objects for viewing can quickly cause performance issues if you query full domain aggregates via repositories. As such aggregates always load all data from it's child entities and value objects as well to allow for performing business logic with all invariants you would end up performing lots of expensive queries which are suited for loading a single aggregate but not many of them at once.

So by querying only what you need for viewing you also address such performance issues.

When following DDD you should usually create or change only one aggregate within a business transaction. So domain models are not suited for query optimization but for keeping the business invariants in tact when writing business data.

View models and corresponding queries are optimized for reading and collecting all data required.

这篇关于架构域模型和视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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