What are the benefits of Persistence Ignorance?

北城以北 提交于 2019-11-26 14:27:06
Stefan Steinegger

Let me explain this with an example. Lets assume your are implementing an application using a classical SQL approach. You open recordsets, change data and commit it.

Pseudo code:

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();

With NHibernate it would look something like this:

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

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

session.Commit();

Persistence Ignorance means that the business logic itself doesn't know about persistence. Or in other words, persistence is separated from logic. This makes it much more reusable.

Move 'logic' to a reusable method:

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

Try to write such a method using resultsets and you know what persistence ignorance is.

If your are not convinced, see how simple a unit test would be, because there aren't any dependencies to persistence related stuff:

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

DDD is something different. There you build up your domain model first (class model) and create the database design according to it. With NH this is very simple, because - thanks to persistence ignorance - you can write and unit test the model and logic before having a (definitive) database model.


Testing: We are testing mappings by creating an instance of the entity, storing it to the database, getting it back and compare it. This is done automatically with lots of reflection. But you don't need to go so far. most of the typical errors show up when trying to store an entity.

You could do the same with queries. Complex queries deserve a test. It's most interesting if the query gets compiled at all. You don't even need any data for this.

For database integration tests, we are using Sqlite. This is pretty fast. NH produces the in-memory database on the fly using SchemaExport (before each test).

Praveen Angyan

I've always thought in term of the domain and while I've used stored procedures, ADO.NET in the past, it's only when I finally moved to NHibernate that I was satisfied with my persistence mechanism.

Domain Driven Design (DDD) puts the emphasis squarely on the domain model. This means that the main focus is creating a conceptual model that forms a common language for both the users and programmers. Users are almost NEVER interested in how you are persisting their information. NHibernate helps you achieve this mindset by making persistance a concern that's secondary to capturing business rules and understanding what the user really wants from the system.

Fluent NHibernate reduces the impact that changes to your domain model have on the underlying mapping files. It also has auto mapping. While you can never totally ignore persistence for your system, NHibernate with Fluent NHibernate allows you to focus on the domain model. If you're not focusing on using a rich Domain model, there's little benefit to NHibernate.

As regards to testing your mappings, you'd be writing tests (or you SHOULD be) no matter what method you use to implement persistence. This isn't extra work that appears just because you are using NHibernate. Just think of testing your mappings as testing that your persistence works correctly.

Again for this Fluent NHibernate is invaluable. It's got a Persistence Specification Testing that's really simple to use for most cases.

PI isn't about using NHibernate. PI stands for ignoring how data will be stored developing domain model. And yes, it is pushing dependency by adding one more abstraction layer. DDD isn't revolutionary - it's more like an idea, an approach how to code using already familiar patterns (most of them are). I.e. - factory pattern or module pattern isn't new too, yet quite important part of DDD.

I started to use NHibernate quite recently too, so - can't provide much details about it. But i got one tip that could be useful for You - try Fluent NHibernate if you haven't done that already.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!