首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >领域驱动设计模型版本

领域驱动设计模型版本
EN

Software Engineering用户
提问于 2021-01-23 21:44:01
回答 2查看 832关注 0票数 2

很抱歉有这么长的问题,但是我喜欢DDD,但是有一个问题我似乎无法解决。

我们在将业务规则添加到聚合根目录时遇到了问题。

当我们从前端进行查询时,我们的体系结构基本上是这样的:

举个简单的例子,我们有一个我们想要的Book

  1. 坚持
  2. 拿来。

这本书

Name必须是10个字符,Author需要15个字符。

这里是TypeScript中的伪代码:

代码语言:javascript
复制
class BookAggregateRoot {
   private _name: string;
   private _author: string;
   private constructor(name: string, author: string) {
       this._name= name;
       this._author= author;
   }

   static create(name: string, author: string): BookAggregateRoot {
       if(name.length < 10) {
           throw error; // not really throwing, its just to show we have an error
       }
       if(author.length < 15) {
           throw error; // not really throwing, its just to show we have an error
       }
       // all data is valid, create the Book
       return BookAggregateRoot(name, author);
   }
}

第一个场景:保存这本书

client -> DTO -> controller -> useCases (从图书类调用创建) ->调用存储库(持久化数据)返回->数据库->数据,存储库(从图书类创建) -> useCases -> mapperToDTO->控制器->客户端。

第二个场景:获取保存的书

获取数据的方式是相同的,但不需要持久化,只需要获取数据: client -> DTO -> controller -> useCases(builds query) -> calls存储库(查询) ->数据库->存储库(3. calls from Book class) -> useCases -> mapperToDTO->控制器-> Client。

只要业务规则不改变,存储的数据和获取的数据具有相同的业务规则就可以了。

问题在于创建AggregateRoot。假设现在我的Book需要一个publishedDate,所有以前不满足从数据库获取的数据的数据在第3步就会失败。

这门课现在变成:

代码语言:javascript
复制
class BookAggregateRoot {
   private _name: string;
   private _author: string;
   private _publishedDate: Date;
   private constructor(name: string, author: string, publishedDate: Date) {
       this._name= name;
       this._author= author;
       this._publishedDate = publishedDate;
   }

   static create(name: string, author: string, publishedDate: Date): BookAggregateRoot {
       if(name.length < 10) {
           throw error; // not really throwing, its just to show we have an error
       }
       if(author.length < 15) {
           throw error; // not really throwing, its just to show we have an error
       }
       if(publishedDate.invalid) {
           throw error; // not really throwing, its just to show we have an error
       }
       // all data is valid, create the Book
       return BookAggregateRoot(name, author, publishedDate);
   }
}

在上面的步骤3,数据总是失败的,因为创建需要一个日期。

我们可以创建一个迁移来修复所有的数据..。但这是正确的做法吗?

请提前通知我是否有更好的设计。:)

EN

回答 2

Software Engineering用户

发布于 2021-01-24 13:26:23

如果业务需要存储额外的字段/列数据,那么本质上有三种可能性:

  1. 您可以修改代码以要求新字段,但不要碰旧数据。这实际上使现有数据无法访问,业务不太可能接受这些数据。
  2. 您可以编写读取代码,这样它就可以处理缺少的字段。这也意味着您必须将数据库本身中的列标记为可选(可空),并且您必须假设字段对于更改后输入的数据也将变为空。
  3. 您可以迁移现有的数据,以包含新字段(这是一个合理的默认值)。这将是一次操作,不会使应用程序的正常流复杂化。
票数 1
EN

Software Engineering用户

发布于 2021-01-24 21:43:55

我不知道您的域的结构,也不知道您有哪些其他域对象,但是您是否深思过如何构造代码。

从某种意义上说,你或我可以创作一本书。创建一本书与出版一本不一样。例如,我可以写一本回忆录,却永远不会出版。

考虑到这一点,是否有可能重组代码,使发布日期是可选的?

代码语言:javascript
复制
public void PublishBook(DateTime datePublished){
   _publishedDate = publishedDate;
}

构造函数不需要检查是否设置了发布日期。此外,我还发现,创建一个表示可以传递给聚合构造函数的数据记录的对象,并根据需要对其进行转换以适应聚合,这是一种很好的模式,可以在重构时更容易地更新聚合,因为您并不总是需要更改构造函数。

检查书集的前提。在更广泛的层面上,也许应该有一个出版商接受一本书的记录,并出版?就像我说的,取决于你的域名的其他部分。无论如何,将对象而不是单个值传递到聚合根将使将来的生活更容易。

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/421443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档