We all know the OO principle 'program to an interface, not an implementation', but I'm wondering how far I should take this.
Say you have a layered architecture with a web layer, a business service layer, a domain objects layer and a DAO layer. It makes sense to have interfaces in the business service layer and DAO layer, because you want to be able to plugin other implementations of those interfaces as required, e.g. for unit testing. It doesn't seem to make to much sense to have interfaces for your web controllers.
But what about the objects in the domain layer, e.g. for a 'Product' or 'Account' domain entity. I can think of several reasons why it would be interesting to have interfaces and seperate implementation classes for the domain layer:
* cleaner dependencies between the packages if the implementations are in a seperate package
* benefits when doing AOP stuff
* ability to 'enforce' an interface
* ability to have a real OO interface, and have some 'less than OO' implementation artifacts in the implementation class to help Hibernate for instance.
However, having seperate interfaces also complicates things because you now have the question: "what implementation do I use?", so you'll need a factory of some sort. For the service and DAO layers, Spring is the factory and wires everything together. But for the domain layer this isn't so easy because you could have situations where one domain object needs to create other domain objects and the domain objects are not typically wired by Spring. So you would need to have a globally visible 'domain object factory' or something. This all seems to get pretty complex...
The Spring JPetStore sample application uses the layered architecture mentioned above, but doesn't use domain layer interfaces.
I'm wondering if anybody has some input on this topic?