views:

161

answers:

5

I am creating the domain model in my system. When designing my model objects, should I make interfaces for each entity object? People have told me that our web tier should not care about the implementation of an entity and we should be able to swap out implementations, but I'm not sure that would ever happen.

For example, if we have a Teacher class that maintains a List of Students, the getStudents method could either be:

public List<Student> getStudents() {
      return this.students;
}

or this:

public List<Student> getStudents() { 
     return someExternalService.retrieveStudents();
}

I understand this benefit, but what is the general practice?

+1  A: 

None of the projects I've ever seen or participated in had interfaces for domain entities.

But in one of my projects I had interface NamedEntity:

public interface NamedEntity {
   int getId ();
   String getName ();
}

All domain entities implemented this interface. It gave me a possibility not to create different jsf converters for different entities but create one converter which used this interface instead of concrete domain classes.

Roman
Nice example. Nitpick: you say none of the projects you've seen or participated had that phenomenon, and then you quickly provide an example of one...
Martinho Fernandes
This upvote revealed bug (or simply unclear behavior) in SO reputation counting.
Roman
I agree. I really don't want any to have an interface but others are disagreeing.
smaye81
@Roman: there's a reputation cap of 200/day based on upvotes. Only bounties and accepted answers will be added hereafter. Also see the faq and meta.
BalusC
@BalusC: see this post http://meta.stackoverflow.com/questions/41683/bug-of-hidden-feature-in-reputation-counting After some thought I think it's not a but.
Roman
Oh, you're already aware of the cap :) Yes, look like some sort of bug. Maybe related to the fact that you accepted an answer after the cap hit.
BalusC
+3  A: 

Unless you have good reason to think you will need to swap-out the model I wouldn't worry about it yet. Based on the YAGNI principle (You ain't gonna need it)

David
Thanks for the answer. I agree with both. I actually have a follow-up to this that I'll post as a separate question. It involves modelling associations.
smaye81
In my opinion, YAGNI applies more to functionality, than design. Interfaces don't contribute to code bloat or complications in testing, for example; in my experience, it's the absence of interfaces for the sake of expediency that's the problem.
Noel Ang
@Noel - I think you're right about it's origins but I think it can be a useful to avoid over-engineering. I have found a couple of occasions to say to someone "You ain't gonna need that" and they can either refute your claim and make a good argument for the addition, or they find they can't justify it and decide/realise it's not really a requirement. I agree in this case there's no great harm in adding interfaces but it could lead to more code being added "just in case".
David
A: 

I can't speak to general practice, but it is hardly just about hiding the implementation.

It's about formalizing the interface as the basis for documentation and contracts.

In abstracting your models out into interfaces, you are creating documentation for service client developers. Depending on your development style, you may or may not already have a formal description of your service (e.g., a WSDL-based description). Interfaces can fill that need.

Noel Ang
Actually that somewhat applies to my situation. There are service client developers basing services off of my model objects, so maybe the interface approach isn't a bad thing.
smaye81
A: 

My general view is that I would not create a one-to-one set of interfaces for the domain models, since this does nothing other than duplicate your domain model's class structure. It doesn't add anything useful.

The two cases I can think of immediately where I would consider introducing interfaces is:

  1. an interface describes the contract/behaviour of some set of classes in the domain model, where it is useful to model that behaviour independantly of the classes which implement it
  2. you need to expose your domain model to external clients and want to hide implementation details from them

In other words, add interfaces if they help you describe behaviour or help you hide implementation details from clients. Other reasons might be valid, but those are two that come to mind.

KarstenF
Yeah, I completely agree. This actually started out as number 2 where we were exposing the domain model to external clients. That approach has since shifted and now I'm stuck with an interface for every model object. I considered getting rid of it, but wanted to check with the community first.
smaye81
+1  A: 

I think there is an important difference between having interface for service to retrieve the object and the model object itself.

At runtime the service to load a model object can differ based on from where you are requesting the data. But the format and type of data object expected does not change, no matter how you create this object. Therefore model objects which carry the state would not need an interface, but service classes to create and load these model objects needs the interface.

The only reason for model objects to have interfaces would make sense if model object is not just a simple bean type of object but object which exposes some kind of behavior as well.

Fazal