Domain driven design 初始化域对象-观察实体、Tell、Don';不问

Domain driven design 初始化域对象-观察实体、Tell、Don';不问,domain-driven-design,solid-principles,tell-dont-ask,Domain Driven Design,Solid Principles,Tell Dont Ask,我试图遵循一些更为流行的设计原则,包括实体设计和领域驱动设计。我的问题是人们如何处理“初始化”域对象 下面是一个简单的例子: 基于SOLID,我不应该依赖于具体化,所以我创建了一个接口和一个类。因为我利用了领域驱动设计,所以我用相关的方法创建了一个对象。(即不贫血) 为了有助于测试和更松散地耦合,我还使用了一个IoC容器来创建这本书。因此,当创建书籍时,它总是被创建为空的。但是,如果一本书没有ISBN和库存,它是无效的 BookstoreBook(string bookISBN, int boo

我试图遵循一些更为流行的设计原则,包括实体设计和领域驱动设计。我的问题是人们如何处理“初始化”域对象

下面是一个简单的例子:

基于SOLID,我不应该依赖于具体化,所以我创建了一个接口和一个类。因为我利用了领域驱动设计,所以我用相关的方法创建了一个对象。(即不贫血)

为了有助于测试和更松散地耦合,我还使用了一个IoC容器来创建这本书。因此,当创建书籍时,它总是被创建为空的。但是,如果一本书没有ISBN和库存,它是无效的

BookstoreBook(string bookISBN, int bookInventory) {..} // Does not exist
我可以有4到5个不同的班级,使用一本书店的书。首先

public class Bookstore : IBookstore
{
   ...
   public bool NeedToIncreaseInventory(BookstoreBook book) { ...}
   ...
}
任何方法如何知道获得一本有效的书?我下面的解决方案似乎违反了“告诉不要问”的原则

a) 每个使用书店书籍的方法是否都应该进行有效性测试?(也就是说,是否需要增加图书有效性的库存测试?我不确定它是否应该知道是什么使书店的图书有效。)

b) 我是否应该在IBookstoreBook对象上有一个“CreateBook”,并“假设”客户机知道他们需要在任何时候调用它来初始化BookstoreBook?这样一来,增加库存的需求就会相信“CreateBook”已经在BookstoreBook上被调用了


我对这里推荐的方法很感兴趣。

首先,我认为你的
书店没有任何真正相关的方法,这意味着它没有任何相关的行为,没有任何业务规则。由于它不包含任何业务规则,它实际上是贫乏的。它只是有一堆能手和二传手。我认为像
AddToInventory
这样的方法最终只向属性添加+1是没有意义的行为

还有,为什么你的
书店的书
知道你的
书店里有多少这类书?我觉得这可能是
书店
本身应该关注的事情

至于a点):不,如果您是通过用户输入创建书籍,您应该在创建新书之前检查提供的数据。这样可以防止系统中出现无效书籍


至于对象的创建,问题是您是否有过不止一种图书类型?如果答案是否定的,您可以删除接口,只需在负责从用户输入创建新书的类中实例化一本书。如果你需要更多的图书类型,一本可能会很有用。

首先,我认为你的
书店图书没有任何真正相关的方法,这意味着它没有任何相关的行为,没有任何业务规则。由于它不包含任何业务规则,它实际上是贫乏的。它只是有一堆能手和二传手。我认为像
AddToInventory
这样的方法最终只向属性添加+1是没有意义的行为

还有,为什么你的
书店的书
知道你的
书店里有多少这类书?我觉得这可能是
书店
本身应该关注的事情

至于a点):不,如果您是通过用户输入创建书籍,您应该在创建新书之前检查提供的数据。这样可以防止系统中出现无效书籍

至于对象的创建,问题是您是否有过不止一种图书类型?如果答案是否定的,您可以删除接口,只需在负责从用户输入创建新书的类中实例化一本书。如果你需要更多的书类型,一本可能是有用的

为了有助于测试和更松散地耦合,我还使用了一个IoC容器来创建这本书

为什么您的IoC容器要创建书籍?这有点奇怪。您的域模型应该是容器无关的(连接接口和实现是您的关注点)

任何方法如何知道获得一本有效的书

域模型知道它得到的是一本有效的书,因为它在接口中就这样说

数据模型知道它正在生成一本有效的书,因为构造函数/工厂方法接受了它的参数而没有抛出异常

每个使用书店书籍的方法是否都应该进行有效性测试

不,一旦您有了一本书,它将保持有效(在您的域模型中不应该定义任何会创建无效数据模型的谓词)

我是否应该在IBookstoreBook对象上有一个“CreateBook”,并“假设”客户机知道他们需要在任何时候调用它来初始化BookstoreBook?这样一来,增加库存的需求就会相信“CreateBook”已经在BookstoreBook上被调用了

有一个用于创建对象的工厂是正常的。看

可以从数据库和许多其他地方创建书籍。我假设其他人已经解决了这个问题,如果他们使用DDD,我想知道他们的方法。我们都应该使用工厂吗?就像你建议的那样,将所需的数据作为输入

实际上只有两种数据来源——您自己的记录簿(在这种情况下,您通过存储库加载数据)和其他任何地方(您需要确保数据符合模型的假设)

为了有助于测试和更松散地耦合,我还使用了一个IoC容器来创建这本书

为什么你的IoC容器要创建书籍?这有点奇怪。你的域模型应该是容器无关的(连接接口和实现是你的关注点)

任何方法如何知道获得一本有效的书

域模型知道它得到的是一本有效的书,因为它在接口中就这样说

数据模型知道
public class Bookstore : IBookstore
{
   ...
   public bool NeedToIncreaseInventory(BookstoreBook book) { ...}
   ...
}