持久性无知有什么好处?

我是DDD + TDD世界的新手。 但是我已经编程了近9年了。

有人能向我解释坚持不懈的好处吗? 典型的nHibernate应用程序只是将类和数据库之间的依赖关系推送到映射文件。

如果我更改类文件或数据库,我必须更改映射文件。 那么不是通过增加一个抽象层来推动依赖? 在我看来,迄今为止,我不认为这是什么革命性的。 但我不确定我是否缺less一些东西。

最后如何testing映射文件? 映射文件中可能会出现错误,我怎么testing它们?

我来举个例子来解释一下。 让我们假设你正在使用经典的SQL方法来实现一个应用程序。 您打开logging集,更改数据并提交。

伪代码:

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"; } 

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

如果你不相信,看unit testing是多么简单,因为没有任何依赖于持久性相关的东西:

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

DDD是不同的。 在那里你首先build立你的领域模型(类模型)并根据它创build数据库devise。 对于NH来说,这非常简单,因为 – 由于持久性的无知 – 您可以在拥有(明确的)数据库模型之前编写和unit testing模型和逻辑。


testing:我们正在testing映射,通过创build一个实体的实例,将其存储到数据库,将其返回并比较它。 这是自动完成的大量反思。 但是你不需要走得太远。 尝试存储实体时,大部分典型错误都会显示出来。

你可以做同样的查询。 复杂的查询应该进行testing。 如果查询得到编译,这是最有趣的。 你甚至不需要任何数据。

对于数据库集成testing,我们使用Sqlite 。 这很快。 NH使用SchemaExport(每次testing之前)即时生成内存数据库。

我一直认为,就域而言,虽然我曾经使用过存储过程,ADO.NET,但只有当我最终移植到NHibernate时,才对我的持久性机制感到满意。

领域驱动devise(DDD)把重点放在领域模型上。 这意味着主要的重点是创build一个概念模型,为用户和程序员形成一个共同的语言。 用户几乎从不关心如何坚持他们的信息。 NHibernate可以帮助你实现这个思维方式,使持久性成为捕获业务规则和理解用户真正想要从系统中获得什么的次要问题。

stream利的NHibernate减less了你的领域模型对底层映射文件的影响。 它也有自动映射 。 虽然你永远不能完全忽略系统的持久性,NHibernate和Fluent NHibernate允许你专注于域模型。 如果你不专注于使用丰富的域模型,那么NHibernate没有什么好处。

至于testing你的映射,你会写testing(或者你应该),不pipe你用什么方法来实现持久化。 这不是因为您使用NHibernate而出现的额外工作。 试想一下testing你的映射,testing你的持久性是否正确。

再次,这个stream利的NHibernate是非常宝贵的。 它有一个持久性规范testing ,在大多数情况下使用起来非常简单。

PI不是关于使用NHibernate的。 PI代表忽略数据如何被存储开发域模型。 是的,它通过增加一个抽象层来推动依赖。 DDD不是革命性的 – 它更像是一个想法,一个如何使用已经熟悉的模式(大多数是)编码的方法。 即工厂模式或模块模式也不是新的,而是DDD的相当重要的部分。

我最近也开始使用NHibernate,所以不能提供很多细节。 但是我得到了一个可能对你有用的提示 – 如果你还没有这样做,请尝试stream利的NHibernate 。

Interesting Posts