Interfaces and Abstract Classes In The Domain
I was just looking at a DDD example that had an interface on nearly every class in the system, including the domain classes. One reason for this is mocking (which I don't favor for the domain anyway) but the other seemed to be to improve the design. This second reason made me think I should disuss why I don't think the "everything needs an interface" approach is a good one for the domain.
First off I should say that the topic has already been discussed.:
I disagree slightly with the two viewpoints, to me you only need abstract classes or interfaces in a minority of cases. In the domain I believe you should only add an abstract class or an interface where you believe that the addition is improving the design, most commonly when it is a useful abstraction.
I do agree with the second view as even when you do have a useful abstraction an interface isn't always enough, you sometimes want to enforce the constraints (bake them in) and an abstract class is better for this.
Having said that I wouldn't take my Customer class and just create an ICustomer interface (or an abstract base class) on it, instead I'd look at the usage of the class and the coupling to it which might lead me to extract meaningful interfaces. In fact in many cases I'll just start out by referring to the concrete Customer domain class, only introducing abstractions where I know they are needed.
In summary only put in interfaces or abstract classes in the domain where they are helping, don't go for what Fowler refers to as "Interface Implementation Pair" approach.
Actually this post sums that up my view nicely.
I'm guilty of creating interfaces for the purpose of testing. Something has always felt wrong about creating these interfaces when there will never be more than one concrete (except during testing). At the same time, I feel that testing is important enough that maybe it's worth it until we come up with something better. I haven't tried TypeMock yet, so maybe that's the answer.
ReplyDeleteYeah it feels wrong to me too, but yeah I have created them for testing too.
ReplyDeleteTypeMock is quite good as it lets you mock concrete classes or types so you can design your domain as you see fit and still have the ability to mock. There is also a free version which is quite good and has most of what you need(though not all of what you might want).
Having said that it does have its detractors not least as it lets you design code that is not mockable (which *could* lead to highly coupled designs)...but like I say I think things are a bit different in the case of your domain model and to be honest I don't do a lot of mocking when testing domain classes anyway.
"One reason for this is mocking (which I don't favor for the domain anyway)"
ReplyDeleteCould you please elaborate on the subject, please?
Personally, I find it very useful to mock (often concrete classes, and more often spies than mocks) object instances that require certain property values which are results of several transactions.
Creating a lot of factories for the tests is in a way testing already tested code.
It might be more work to refactor the spies/mocks than the factories, but that's not for sure (in my experience).