Tuesday, October 31, 2006

Java Interfaces or Abstract Classes?

These days there's a very interesting discussion on the Domain-Driven Design mailing list about the use of "pure" Java interfaces (the one expressed by the interface keyword) or classic abstract classes for modeling and implementing domain objects.

I strongly suggest you to read the whole thread.

But for now, let me summarise a bit.

I'm a strong supporter of the use of interfaces in domain model.
As I already explained in one of my old posts, my main point is that pure interfaces let you clearly separate the business behaviours and contracts from implementation details. In particular, they let you clearly express what is the published interface, and what the public one: this enables you to write code that depends only on interfaces that actually express domain concepts, without worrying about implementation-only methods.
As a side note, interfaces let you easily test your system.

Those that prefer to use abstract classes argue instead that interfaces cannot fully express domain contracts, because they are just "signatures with no body", while abstract classes carry an implementation and so are able to express those missed contracts.
Moreover, they mainly see interfaces as a way of enabling multiple implementations/inheritance: if no multiple implementation is needed, there's also no need for an interface.
Finally, they think interfaces ara against evolutionary design because evolving the design by adding a method to an interface breaks all implementors.
Following their point of view, so, interfaces for domain objects are mostly just one more indirection, just one more useless source file.

I fully understand their points, but I disagree with many of them.
I obviously cannot say that the pure interfaces approach is absolutely better than the other: everything has pros and cons, but I still prefer it.
It is not because using abstract classes is wrong.
Too bad, I think there's a base misunderstanding between the two. Trying to clarify, I'd like to highlight the following points:

  • It is true that you cannot fully express all you contracts using just interfaces: in fact, I suggest to use interfaces plus abstract classes, or eventually AOP aspects expressing business contracts.

  • Programming by "pure" interfaces doesn't mean you have to make an interface for every class: it just means you have to make an interface for main business concepts whose interface methods will be referenced in your code.

  • When you program by ("pure") interfaces and you are in the situation where you need to add a method in your interface, if that method doesn't fit into all implementors, this means that you have wrong interfaces and you need refactoring. This is because the adding of a method into an interface must be driven by its contracts, and if an implementor doesn't need that method, it may be that the implementor should not have that interface.

  • Pure interfaces are not against evolutionary design, because you can introduce them inch by inch in your design and use refactoring for supporting changes.

That said, I'd like to hear your thoughts, my reader ... any opinion?


Anonymous said...

The story from the other camp .. the guy who started it all .. It was a thoroughly enjoyable discussion in the mailing list.

Anonymous said...

Hi Sergei -

U have mentioned in ur post about using pure interfaces + aspects to express domain contracts. Please have a look at this post which tries to do the same. Would love to hear your observations on this.