Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

If you are familiar with the Java RDF and OWL engine Jena, then you have run across their philosophy that everything should be specified as an interface when possible. This means that a Resource, Statement, RDFNode, Property, and even the RDF Model, etc., are, contrary to what you might first think, Interfaces instead of concrete classes.

This leads to the use of Factories quite often. Since you can't instantiate a Property or Model, you must have something else do it for you --the Factory design pattern.

My question, then, is, what is the reasoning behind using this pattern as opposed to a traditional class hierarchy system? It is often perfectly viable to use either one. For example, if I want a memory backed Model instead of a database-backed Model I could just instantiate those classes, I don't need ask a Factory to give me one.


As an aside, I'm in the process of writing a library for manipulating Pearltrees data, which is exported from their website in the form of an RDF/XML document. As I write this library, I have many options for defining the relationships present in the Peartrees data. What is nice about the Pearltrees data is that it has a very logical class system: A tree is made up of pearls, which can be either Page, Reference, Alias, or Root pearls.

My question comes from trying to figure out if I should adopt the Jena philosophy in my library which uses Jena, or if I should disregard it, pick my own design philosophy, and stick with it.

share|improve this question
1  
one can call it, "coding/designing against contracts" to remove direct dependencies. –  Yusubov Jun 29 '12 at 21:14
add comment

2 Answers

up vote 2 down vote accepted

There are a few advantages to using only interfaces as the public face of your API:

  • You can create dynamic proxies that implement an interface (read more). Dynamic proxies are often used to implement transparent RPC mechanisms (whereas objects "live" on a server but can be retrieved and operated on by a client application). One can proxy classes, but only through hacks. Thus, APIs which are implemented using proxies can be easily exposed for RPC.

  • It opens up to having different implementations of the interfaces which can be switched transparently. So, you can have an API which has several independent implementations which use different techniques (i.e. someone might create an implementation which is more performant- you could swap in their implementation with no changes on your code).

Of course, it is a kind of pain; you have to use factories to instantiate the APIs classes, and it makes the API implementation code more complex and redundant (all public methods are duplicated).

I think a neat solution is Dart's- each class implicitly declares an interface consisting of the class' public methods, thus avoiding the code duplication.

About the need of factories, I'm not sure a better solution exists. One could reimplement an API overwriting the original classes' namespace, but it's kind of hackish and I think it would pose problems, esp. with tooling.

share|improve this answer
add comment

What alex said is correct and are the best reasons I can think of for using interfaces wherever possible. The dynamic proxy one is important because they cannot be used with classes, even abstract ones!

I am not familiar with Jena in particular, but a strong preference for interfaces is quite common in OOP.

The only danger to be careful of is the over-use of interfaces. I can tell the programming-to-the-interface best practice has been abused when I see tons of interfaces with only a single implementation named after the interface and the word "Impl".

public interface WidgetManager {
    ...
}

public class WidgetManagerImpl implements WidgetManager {
    ..
}

Could have just made WidgetManager a class and be done with it. Instead, we've doubled the number of Java types needed and added an extra hoop to jump through when debugging.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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