views:

151

answers:

2

I am trying to keep my domain layer as "pure" as possible without weaving in persistence or other infrastructure concerns. However, there are times when my domain layer needs to use the services of either an RDBMS or other external dependency and I'm not sure how to deal with it.

For example, each domain object in my app implements an IValidatable interface which is invoked by clients to a get a list of broken rules that prevent the object from being persisted. In a few cases, the aforementioned validation routine involves making a call to a DAO class to check on the existence of a specific record. We are not using an ORM; instead we use a persistence layer built using the Data Access Object pattern. Should I just create a service/wrapper class around this database access and have my domain object collaborate with it? Is adding this level of indirection acceptable or am I still polluting my domain object?

+2  A: 

The usual answer would be to use an object-relational interface of some sort. Your Domain layer presents the interface of your domain model. You have a relational data base under the covers, and you need a layer between them to perform object-relational mapping. You say "we are not using an ORM" but in fact you are: you're just doing that mapping directly in the domain layer.

The problem of making that mapping is known as the object-relational impedance mismatch problem. If you insist on not identifying an explicit ORM layer, then yes, you should write classes to encapsulate the details of using the DBMS, (Of course, when you do, you will ave introduced ORM classes there.)

Really, it's very difficult to avoid having some ORM layer.

Charlie Martin
+1  A: 

I've long been of the view that you cannot hide knowledge of persistence in a persistent domain object. Trying to do so becomes increasingly unnatural and introduces weird side effects. So in other words, I think it's fine to build in knowledge of persistence in the domain layer, but not necessarily the exact means of persistence; a DAO interface should be used.

I should add that, depending on your validation check, you are subject to a race condition. You should be prepared to handle any constraint exceptions that could occur due to this.

nilskp