41

我是 DDD+TDD 世界的新手。但我从事编程工作将近 9 年了。

有人可以解释一下坚持无知的好处吗?典型的 nHibernate 应用程序只是将类和数据库之间的依赖关系推送到映射文件。

如果我更改类文件或数据库,我必须更改映射文件。那么它不只是通过添加一个抽象层来推动依赖吗?在我看来,到目前为止,我不认为这是革命性的。但我不确定我是否遗漏了什么。

最后如何测试映射文件?映射文件中可能会出现错误,我该如何测试它们?

4

3 回答 3

51

让我用一个例子来解释这一点。假设您正在使用经典的 SQL 方法实现应用程序。您打开记录集、更改数据并提交它。

伪代码:

trx = connection.CreateTransaction();
query = connection.CreateQuery("Select * from Employee where id = empid");
resultset = query.Run();
resultset.SetValue("Address_Street", "Bahnhofstrasse");
resultset.SetValue("Address_City", "Zürich");
trx.Commit();

使用 NHibernate,它看起来像这样:

emp = session.Get<Employee>(empid);

// persistence ignorant 'logic'
emp.Address.Street = "Bahnhofstrasse";
emp.Address.City = "Zürich";

session.Commit();

持久性无知意味着业务逻辑本身不知道持久性。或者换句话说,持久性与逻辑是分开的。这使得它更加可重用。

将“逻辑”移动到可重用的方法:

void MoveToZuerichBahnhofstrasse(Employee emp)
{
  // doesn't have anything to do with persistence
  emp.Address.Street = "Bahnhofstrasse";
  emp.Address.City = "Zürich";
}

尝试使用结果集编写这样的方法,您就会知道什么是持久性无知。

如果你不相信,看看单元测试有多简单,因为与持久性相关的东西没有任何依赖关系:

Employee emp = new Employee();
MovingService.MoveToZuerichBahnhofstreasse(emp);
Assert.AreEqual("Bahnhofstrasse", emp.Address.Street);
Assert.AreEqual("Zürich", emp.Address.City);

DDD 是不同的东西。在那里你首先建立你的领域模型(类模型)并根据它创建数据库设计。使用 NH,这非常简单,因为 - 由于对持久性的无知 - 您可以在拥有(确定的)数据库模型之前编写和单元测试模型和逻辑。


测试:我们通过创建实体实例、将其存储到数据库、取回并进行比较来测试映射。这是通过大量反射自动完成的。但你不需要走那么远。尝试存储实体时会出现大多数典型错误。

你可以对查询做同样的事情。复杂的查询值得测试。如果查询完全被编译,那将是最有趣的。您甚至不需要任何数据。

对于数据库集成测试,我们使用Sqlite。这是相当快的。NH 使用 SchemaExport 动态生成内存数据库(在每次测试之前)。

于 2009-05-25T09:49:03.447 回答
7

我一直在考虑域,虽然我过去使用过存储过程,ADO.NET,但只有当我最终转向 NHibernate 时,我才对我的持久性机制感到满意。

领域驱动设计 (DDD) 将重点直接放在领域模型上。这意味着主要重点是创建一个概念模型,为用户和程序员形成一种通用语言。用户几乎从不对您如何保存他们的信息感兴趣。NHibernate 通过使持久性成为捕获业务规则和了解用户真正想要从系统中得到什么的次要问题来帮助您实现这种心态。

Fluent NHibernate减少了对域模型的更改对底层映射文件的影响。它还具有自动映射功能。虽然您永远不能完全忽略系统的持久性,但 NHibernate 与 Fluent NHibernate 允许您专注于域模型。如果您不专注于使用丰富的域模型,那么 NHibernate 几乎没有什么好处。

至于测试您的映射,无论您使用什么方法来实现持久性,您都将编写测试(或者您应该编写测试)。这不是因为您使用 NHibernate 而出现的额外工作。只需将测试您的映射视为测试您的持久性是否正常工作。

再次对于这个Fluent NHibernate来说是无价的。它有一个持久性规范测试,在大多数情况下使用起来非常简单。

于 2009-05-25T07:22:57.067 回答
2

PI 不是关于使用 NHibernate。PI 代表忽略数据将如何存储开发领域模型。是的,它通过添加一个抽象层来推动依赖。DDD 不是革命性的——它更像是一种想法,一种如何使用已经熟悉的模式(大多数都是)进行编码的方法。即 - 工厂模式或模块模式也不是新的,但它是 DDD 的重要组成部分。

我最近也开始使用 NHibernate,所以 - 不能提供太多关于它的细节。但是我得到了一个可能对您有用的提示 -如果您还没有这样做,请尝试Fluent NHibernate 。

于 2009-05-25T07:21:30.437 回答