views:

1569

answers:

15

Hi,

I agree, that programming against interfaces is a good practice. In most cases in Java "interface" in this sense means the language construct interface, so that you write an interface and an implementation class and that you use the interface instead of the implementation class most of the time.

I wonder if this is a good practice for writing domain models as well. So, for example if you've got a domain class Customer and each customer may have a list of Orders, would you generally also write interfaces ICustomer and IOrder. And also would Customer have a list of IOrders instead of Orders? Or would you use interfaces in the domain model, only if it is really driven by the domain, e.g. you've got at least two different types of Orders? In other words, would you use interfaces because of only technical needs in the domain model, or only when it is really appropriate with respect to the actual domain?

+18  A: 

Writing interfaces "just because" strikes me as a waste of time and energy, not to mention a violation of the KISS-principle.

I write them when they are actually useful in representing common behavior of related classes, not just as a fancy header file.

Rik
+9  A: 

Don't over design your system. If you find out that you have several types of Orders and think it's appropriate to declare an interface for Orders than refactor it when the need arises. For domain models, the probability is high that the specific interface will change much over the lifetime of development, so it rarely useful to write an interface early.

Eran Galperin
+1  A: 

I usually only use interfaces where it makes sense on smaller projects. However, my latest job has a large project where nearly every domain object has an interface. It's probably overkill and it's definitely annoying, but the way we do testing and use Spring for dependency injection sort of requires it.

Matt
+1  A: 

We mostly write web applications with Wicket, Spring and Hibernate and we use interfaces for Spring Beans, e.g. Services and DAOs. For these classes, interfaces make totally sense. But we also use interfaces for every single domain class and I think this is just overkill.

cretzel
+1  A: 

Even if you are pretty sure there is only going to be one concrete type of a model object, using interfaces makes mocking and testing somewhat easier (but these days there are framworks that can help you generate mock classes automatically, even for concrete Java classes- Mockito, JTestR, Spring, Groovy...)

But I even more often use interfaces for services, since it is even more important to mock away them during testing, and programming against interfaces helps you think about stuff like encapsulation.

Lars Westergren
+4  A: 

Interfaces are an excellent way of isolating components for unit testing purposes and general dependency management. Saying that, I often prefer abstract classes so at least some of the common behaviour is offloaded there rather than forcing some of the duplication that interfaces bring. Modern IDEs make it quick and easy to generate interfaces so they aren't that much work :-)

Phil Bennett
+1  A: 

I'd recommend staying lean and agile - don't do anything until you need to do it, then let your IDE do the refactoring for you when you need it.

Its pretty trivial in IDEA/eclipse to turn a concrete class into an interface when you decide you need one.

Then use dependency injection with Spring or Guice if you have many implementations of the interface to inject into the places in your code you're using 'new'

James Strachan
+1  A: 

Writing interfaces for domain classes can make sense if you're using it for unit testing. We use Mock objects in unit testing. So, if you have an interface for a domain object and your domain object itself is NOT ready but your client can test its use of the interface by the help of mock objects.

Intefaces also test multiple implementations of your interfaces for your domain model. So, I don't think it is always overkill.

anjanb
+1  A: 

I think that the main reason for programming against interfaces is testability. Hence, for the domain objects - just stick to POJOs or POC#Os :) etc., i.e., just keep your classes from adding any specific framework so to prevent them from differend build and runtime dependencies and that's all. Creating interfaces for DAOs is a good idea though.

martinsb
+1  A: 

Writing interface before it gets needed (either for testing or architecture) is an overkill.

Additionally, writing an interface manually is a waste of time. You can use Resharper's refactoring "Pull Members" to let it create new interface out of the specific class in a matter of seconds. Other refactoring tools that integrate with IDE should have similar functionality as well.

Rinat Abdullin
+3  A: 

No, I only use interfaces on Domain Objects to keep them loosely coupled. For me the main hook of developing my own code with interfaces is that I can easily create mocks when doing Unit Testing. I don't see the point in mocking Domain Objects as they don't have the same dependencies that a service layer or DAO layer class would have.

This certainly doesn't mean to stray away from using Interfaces in Domain Objects. Use where appropriate. For example, lately I've been working on a webapp where different types of Domain Objects correspond to permalink pages in which users can leave comments. So, each of these Domain Objects now implement the "Commentable" interface. All of the comment-based code is then programmed to the Commentable interface instead of the Domain Objects.

bpapa
A: 

That's another thing to keep in mind that I've run in to, especially with generated domain and DAO objects. A lot of the interfaces are just too specific. Say a lot of domain objects have an ID and a status field, Why don't they share a common interface? This has caused me frustration, an unnecessarily flat (inheritance-wise) domain model.

Matt
+1  A: 

We extract interfaces from everything just because it assists in testing (mocking) and for stuff like AOP. Eclipse can do this automatically: Refactor->Extract Interface.

And if you need to modify the class later, you can use Refactor->Pull Up... to pull up the methods you need onto the interface.

MetroidFan2002
+1  A: 

*I do it because I need it for creating proxies of my domain objects.

Wouter Lievens
+1  A: 

Actually, this question is an example of the common misunderstanding about "programming against interfaces".

You see, this is a very good principle, but it does not mean what many people think it means!

"Program to an interface, not an implementation" (from the GoF book) means just that, not that you should go out of your way to create separate interfaces for everything. If you have an ArrayList object, then declare the variable/field/parameter/return type as being of type List. Client code will then only deal with the interface type.

In the "Effective Java" book from Joshua Bloch, the principle is expressed more clearly, in "Item 52: Refer to objects by their interfaces". It even says, in bold letters:

It is entirely appropriate to refer to an object by a class rather than an interface if no appropriate interface exists.

For unit testing, the situation is entirely dependent on the capabilities of the mocking tool used. With my own tool, JMockit, I can write unit tests just as easily for code that uses interfaces and Dependency Injection as for code that uses final classes instantiated from inside the code under test.

So, for me, the answer is: always use interfaces that already exist, but avoid creating new ones if there is no good reason to do so (and testability, by itself, should not be one).

Rogerio