我是DDD + TDD世界的新手。但是我从事编程已经有将近9年了。
有人可以向我解释持久性ignornace的好处吗?典型的nHibernate应用程序只是将类和数据库之间的依赖关系推送到映射文件。
如果更改类文件或数据库,则必须更改映射文件。那么,难道不是仅仅通过增加一个抽象层来 push 依赖关系吗?在我看来,到目前为止,我认为这不是革命性的。但是我不确定是否丢失了一些东西。
最后,如何测试映射文件?映射文件中很可能会出现错误,我该如何测试?
最佳答案
让我用一个例子解释一下。假设您正在使用经典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即时生成内存数据库(在每次测试之前)。