More Persistence Patterns in MSDN

EDIT:  I missed something the first time around.  If some persistence tool makes it so that I can only put business logic in my domain models using a partial class, that’s an automatic FAIL!

 

My latest article in the Patterns in Practice column is in the June edition of MSDN Magazine.  This time around I continued the discussion about persistence patterns with the Unit of Work Pattern and some (very watered down) discussion about Persistence Ignorance.  Granted, this isn’t my favorite article I’ve ever written, but these are important topics that I think everyone needs to consider as part of their persistence strategy.  For you folks out there that say “bah, humbug, I don’t need no POCO,” I think you need to at least consider the issues before you blow it off.

To summarize, *I* think Persistence Ignorance is important for these reasons in descending order of importance (you can argue whether 3, 4, or 5 is more important):

  1. Can I exercise my business logic and user interface without having to drag in the database?  This is crucial for efficient unit testing.  With the way the Entity Framework v1 did lazy loading, the answer is no.  With NHibernate and maybe EF v4, the answer is yes.
  2. Can I design my object structure and database model independently?  In other words, don’t make the database model dictate the shape of the object model.  As the complexity of the system grows beyond dirt simple, codegen’ing the object model from the database tables is teh suck.
  3. How easy is it to make small incremental or evolutionary changes to my domain model?  Again, I think code generation schemes that start from a complete database model and generate the object model are optimized for BDUF and become unwieldy in the face of small changes.  Solutions that require change tracking to be coded directly into the domain model make incremental changes harder because of the extra weight of changing or adding new properties to the model.
  4. What strictures does my persistence tooling place on my object model?  Marking properties as virtual just to enable lazy loading is annoying.  Having to expose public properties of inner collections like Lists or Sets destroys encapsulation and is completely unacceptable to me.  My persistence tool shouldn’t force me to compromise encapsulation.  I really don’t want to have to inherit from a base class in the framework.  It’s very valuable to use my own Layer Supertype for my domain model rather than blowing my one superclass on infrastructure goo.
  5. Lastly, I don’t want persistence methods cluttering up the public interface of my domain model classes.  Interface Segregation Principal baby!

For the record, it does look like from a shallow reading that the new EF v4 looks much better than EF v1 did — but still falls well short of NHibernate.  It all depends on how much you really care about this stuff.  *I* care deeply about the ability to design continuously and incrementally, clean separation of concerns, and test driven development.  To me, the object model is the main player in the application and the database is nothing but a persistence mechanism.  If you don’t care about those things, or are just simply too engrained in data centric orthodoxy to change, then you can happily ignore that list.

 

Go ahead and argue away I suppose.  I’m offline for the next 3-4 days, so you automatically get the last word in;)

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Brian

    @Tyler,
    Agreed and extremely well said. We have a several systems whose only ‘data’ comes from web services; we also have a system that runs completely in ‘state’ and the state itself gets persisted to a file system (legacy).

    Also:
    “Having to expose public properties of inner collections like Lists or Sets destroys encapsulation and is completely unacceptable to me. My persistence tool shouldn’t force me to compromise encapsulation.”

    I feel the same about my testing tool, code-gen tool, and any other tool. Tools should drive design and I think you hit a nail on the head there.

    I think there are several good points in the post that can be ‘generalized’ into more than just ORM.

  • Eric

    @Craig

    Until Microsoft moves on to their next latest and greatest marketing-driven Data Access Strategy and the Entity Framework joins LINQ to SQL in the Data Access Strategy graveyard.

  • Craig

    Keith,

    I have to agree. nHibernate is great, but if there’s one thing that history teachs is that easy stuff embedded in the tools wins. Maybe not EF4, but there will be a 5, and a 6 ….

  • http://www.tsjensen.com/blog/2009/04/28/PLINQO+A+Better+LINQ+To+SQL.aspx Tyler

    It’s an interesting, but I think flawed, assumption that the ORM generated code from your data tables, views and sprocs must be used as your domain model. The assumption that the domain model ought to be persisted to the database via some framework and config file system is even more interesting and even more flawed, I think. But I could be wrong. My wife assures me that it’s happened before.

  • http://blog.keithpatton.com/2009/05/30/Entity+Framework+POCO+Repository+Using+Visual+Studio+2010+Net+40+Beta+1.aspx Keith Patton

    Hi Jeremy,

    “For the record, it does look like from a shallow reading that the new EF v4 looks much better than EF v1 did — but still falls well short of NHibernate”

    Having worked with NH for a few years EF v4 does look to be at least architecturally similar freedoms. The gap has reduced such that i would have to question whether the gap is that large.

    Also note NH does not have great tool support and no enterprise ready Linq provider to speak of, two of the key reasons EF v4 will likely win out.

  • http://blog.danielfernandes.net Daniel Fernandes

    Jeremy :
    Regarding point 2.
    I’d be interested to know how you can get a domain model not to be constrained by a physical data model using an ORM tool such as NHibernate.
    If you do want to let DBAs control the schema then inevitably either the structure will leak into the domain model and it’s not going to be pretty or you’re going create a domain model that is in itself is composed of “data” related entities that are managed by NHibernate.

    Having used NHibernate against a terrible legacy schema that we didn’t have the right to change and not enough time to create a new database I can say that one has to be cautious when promoting ORM as the saviour to all your data access problems.

    On a side note, have you put any thought lately on document databases, whether it’s by using purpose built ones such as CouchDb or going half way there and serializing data structures that would provide no benefit whatsoever in being denormalized, instead creating maintenance hell for the future.

    Daniel

  • Shawn de Wet

    I just want to make sure I understand something correctly. You say “Having to expose public properties of inner collections like Lists or Sets destroys encapsulation and is completely unacceptable to me”.
    Does this mean it is unacceptable to you have a SalesOrder Class that exposes a MyOrderLines property returning a collection of the order lines belonging to the SalesOrder? If so, would you please expand on 1) how you approach this scenario instead, and 2) why it destroys encapsulation (aren’t the OrderLines are a very important aspect of a SalesOrder?)

  • Harper Shelby

    Ironically, I asked a couple of related questions over on StackOverflow – and couldn’t get what I consider to be a good answer. While I do agree that NHibernate appears to be better at this than many other options, I still see way too many constraints on the way my domain objects are designed. Here’s a link – maybe you know a bit more that I haven’t seen yet! http://stackoverflow.com/questions/926668/do-any-net-orms-use-constructors-properly