9

I was reading JDOM's website.

Why is the JDOM API defined in terms of concrete classes rather than interfaces?

Jason Hunter summarizes the arguments against an interface-based API for JDOM:

With interfaces everything becomes a factory, elements have to be 'imported' into new documents instead of just added, features like long-term serialization cannot be guaranteed, and the list goes on.

We started with interfaces actually. During our pre-release review to some peers we received the feedback we should try concrete classes. We did, and the design was much better for it.

I am a beginner designer. All the advice I have heard about till now is advising against using designing with concrete classes.

May be using concrete classes are appropriate in certain places. Are there any common class problems for which using concrete classes in design is okay?

4

5 Answers 5

6
  • Inheritance creates dependencies on implementation, which might be a big problem regarding maintainability. The corollary of this is that you can safely use inheritance and concrete classes when dealing with data transfer object, which by definition contain almost no implementation. You can also use inheritance of concrete classes when you want this dependency. You might want to use an abstract class containing the common methods (usually utility functions) at the the top of the hierarchy in this situation.
  • When using a concrete class hierarchy, do not forget to apply the Liskov Substitution Principle.
  • There is no problem with using concrete classes for clients (i.e. classes that uses, not classes that are used).
  • IMHO you can use concrete classes until there are things to change. The Open/Closed Principle would tell you to use interfaces to avoid coupling, but regarding the You Ain't Gonna Need It Principle you might consider using concrete classes until the moment when you need to change something in the implementation. The problem is that you would have to change every client of your classes the first time something changes somewhere. While you only have one possible tool to do something, you can use concrete classes IMO.

[EDIT] JDOM's website takes java.io.File as an example, but this is definitely an interface based design as one can manipulate a java.io.File instance as if it were only a Serializable. In this situation only "creators" would know the concrete class

3
  • There are two conflicting definitions of "value object" floating around. Yours seems to be the less common one, also known as "data transfer object". Commented May 9, 2012 at 11:48
  • @MichaelBorgwardt Thx for pointing this out as I did not mean "data transfer object" only : I edit my answer Commented May 9, 2012 at 12:04
  • 1
    LSP is important for any subtyping relationship, interface implementation as well as inheritance.
    – user7043
    Commented May 9, 2012 at 12:32
3

From the JDOM site:

Jason (Hunter) founded the JDOM project in early 2000 along with Brett McLaughlin

That is, around the time Java 1.3 was being introduced. There was nothing in the way of maturity when it came to Java development--the most experienced developers only had 4 years using Java at best. There were no broadly used IoC containers, no Hibernate. Apache Struts was just getting its start.

Which is all to say that Jason and Brett were just wrong. A lot of people didn't "get it" yet. If they had C++ backgrounds, well, you didn't need interfaces in C++ (well, they were there in C++, but you didn't really need them, right?), why the heck use them in Java? Well, there's a lot of good reasons, which others can direct you to.

They were definitely wrong about

anything that can be done with interfaces can be done with subclassing

Java does not allow multiple inheritance of classes, but it does allow the implementation of multiple interfaces. That can make a real difference.

3

Please remember, regarding your question, that in Software Development there are several ways to solve a problem, and if some developer uses a technique different than yours, that doesn't means it solution is wrong.

One of those cases is "interfaces" versus (base) "classes". There are situations where the same goal can be achieve with both techniques.

To make things, more complicated, there are several uses of interfaces, just to mention:

  • one is to design a "contract" or "specification" without "implementation"
  • other, to add functuonality to an existing, not new, class or hierarchy of classes
  • complementary to previous, to allow share access among different objects, technologies, example: Enterprise Beans, CORBA, COM, WebServices
  • to emulate multiple inheritance

Your question applies to the first point.

When you want to develop a class hierarchy, not just a single class, and several classes are intended to share some specific features, you may want to start with a base class, even if it can be done with an interface.

And, leave interfaces for the others scenarios.

A good example are widgets (controls) libraries.

I suggest, that take a look to other programming languages how do they use interfaces & classes like: PHP, Delphi (Object Pascal), C#.

Cheers.

1

API design rules are really a specific thing. I'm not sure you should conclude anything from that FAQ in terms of how you should design your day-to-day code.

For your regular code, it's still true that you'll use interface or abstract class inheritance a lot more often than vanilla inheritance IMO.

To get a good understanding of that rule, you have to place yourself not from the standpoint of a derived class vs its superclass, but from the standpoint of an object that has a dependency to another object. It's almost always better to depend on an abstraction rather than a concrete implementation because it allows you to accept a whole series of different classes as dependencies, relying on their contract and not their implementation details.

The first use for this is often in unit tests - if you really want to unit test your class in complete isolation, you do that against fake implementations of your dependencies that are different from the real implementations that will be used in production.

0

You generally want an interface for anything that gets passed as a parameter or returned, essentially so you can decouple the class from its dependencies.

SO if we are looking for a class we never pass around normally exceptions spring to mind. I'm not a Java developer, but certainly in other similar languages I don't think I've seen interfaces defined for exceptions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.