2

What is the purpose of using interfaces for domain entities?

In our project, we are using interface for domain entities. Inside the interface, there are only getter and setter methods, not even any domain logic.

Is using an interface for entities like this useful? Is this good practice?

Thanks.

magicbacon
  • 321
  • 2
  • 4
  • 19

3 Answers3

6

There are plenty of reasons why it's a good idea sometimes but it really depends on the scope of the project.

First of all: your statement "...not even any domain logic." doesn't make sense, there can't be any logic in an interface, interfaces can't have any logic, only method signatures.

The main reason why this is done is to support multiple implementations of the domain objects for different uses.

Reasons why you might want to code your domain objects to interfaces:

  1. Serialization - sometimes you want to create serializable versions of your domain objects but don't want to mix that code up with the code you use for your core app. For example, you might have an implementation of your Person object that you just use to serialize to JSON for your webapp.

  2. Shared API - you might want to distribute a public API version of your code that has different implementations of your objects, or you might even just want to make the interfaces available to another group (or client, or vendor)

  3. Support for a legacy implementation - maybe you have some data in an old database that you need to build a connector for that involves a different implementation of your domain objects to pull the data out.

  4. Testing - having interfaces for your core classes makes unit testing a lot easier since you can quickly stub out methods you don't need for testing.

Rick Mangi
  • 3,761
  • 1
  • 14
  • 17
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackoverflow.com/rooms/160855/discussion-on-answer-by-rick-mangi-why-use-interfaces-for-domain-entities). – elixenide Dec 09 '17 at 19:03
3
  • I have never worked on a project where this kind of thing goes on;
  • it is not typical design;
  • I have never heard or read anyone claiming it is a good practice;
  • I can't think of any benefit from such a design;
  • I can think of nuisances it causes.

When you access a public instance field of a data object, you are already "programming to contract"—that's all the contract you get from a bean. The layer of accessors adds nothing, let alone another layer of interface. Java Beans are an admission of the fact that much data is just that – data – and encapsulating it behind a contract only hurts its utility. FP, probably the nicest programming paradigm in existence, got this point right.

One may ask (it's @pst, actually :), what if different entities implement different serialization strategies? What if they store data differently internally? Perhaps one is super-duper-over-clever and does lots of bit-twiddling for "performance" reasons.

Yes, we can certainly imagine some scenario where this is actually called for, but it goes the other way around: first you realize you'll be doing such a project, then you introduce interfaces around beans. You don't do it up front because "maybe, just maybe, this crazy requirement will come about in the middle of our project". And practice clearly shows that this almost never happens.

Also, don't forget that constructors are out of question in such a design. Enforcing a project-wide policy to write abstract factories for each and every piece of domain data—and for no definite reason—is definitely not what one could call a reasonable design choice.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • @pst Which one are you interested in? The negatives hardly lend themselves to expansion :) – Marko Topolnik Feb 05 '13 at 19:18
  • I am fairly interested in #5 (nuisances, as the bold drew my eye), but it would also be nice if some "common benefits of interfaces" could be ruled/reasoned-against in #4. (I mean, after all, isn't "programming to contract" a Good Thing?) –  Feb 05 '13 at 19:25
  • @pst When you access a public instance field of a data object, you are already "programming to contract"---that's all the contract you get from a bean. The layer of accessors adds nothing, let alone another layer of interface. Java Beans are an admission of the fact that much data is just that -- data -- and encapsulating it behind a contract only hurts its utility. FP, probably the nicest programming paradigm in existence, got it right. – Marko Topolnik Feb 05 '13 at 20:18
  • What if I want to use a different bean/entity? Does not using an interface reduce coupling? –  Feb 05 '13 at 20:22
  • @pst A different bean with the exact same properties? How is that even possible? There are no two ways to implement the contract of "sets the `firstName` property, a `String`, to the value of the argument". – Marko Topolnik Feb 05 '13 at 20:27
  • Well, why not? What if different entities implement different serialization strategies? What if they store data differently internally? Perhaps one is super-duper-over-clever and does lots of bit-twiddling for "performance" reasons. –  Feb 05 '13 at 20:34
  • @pst I knew you'd come up with some imaginative example :) Yes, we can certainly imagine **some** scenario where this is actually called for, but it goes the other way around: **first** you realize you'll be doing such a project, **then** you introduce interfaces around beans. You don't do it up front because "maybe, just maybe, this crazy requirement will come about in the middle of our project". And practice clearly shows that this almost never happens. – Marko Topolnik Feb 05 '13 at 20:40
  • @pst Oh, and don't forget that constructors are out of question in such a design! Would you really enforce a project-wide policy to write abstract factories for each and every piece of domain data? I'm sure you wouldn't because nobody sane would. – Marko Topolnik Feb 05 '13 at 20:41
  • I agree - but didn't quite realize so until I started using DI. It was then that I realized that only *some* things are [testable] Services and most other types are just an implementation detail. I think this answer would be better if moving some of the information from these comments into it. –  Feb 05 '13 at 20:41
  • 1
    @pst Did that. Thanks for engaging feedback :) – Marko Topolnik Feb 05 '13 at 20:49
1

I have seen some developers who take the "code to an interface" advice way too far. They think they should always be using an interface just in case it might come in handy one day.

Shane
  • 2,629
  • 6
  • 32
  • 39
  • Even "plain" JavaBeans are a questionable practice, especially in today's world of aspects that can advise field access. Wrapping them in another layer of abstraction is... masochistic. Masochism was a general trend in Java in the mid 2000's, to be fair, but those years are luckily behind us. – Marko Topolnik Feb 05 '13 at 19:22
  • @MarkoTopolnik No, no. Unfortunately Java still has lot of market share - and has done little to improve the fundamental language :( While some of the Beans-Are-Everything nonsense has died, this just means it's "less painful", which is different than "non painful". (This thought was spawned from my dislike of when a company claims to have an "Environmentally Friendly" product - in most cases the correct label is "Less Environmentally Damaging".) –  Feb 05 '13 at 19:29
  • 1
    @pst I'm referring to much more modest goals: the recent trend trend in Java has been finding ways to reduce boilerplate, as opposed to previously, where the trend was to **increase** boilerplate. – Marko Topolnik Feb 05 '13 at 19:58
  • @MarkoTopolnik Well, there isn't much I can say to that, so have a (tiny) +1 instead. –  Feb 05 '13 at 20:22