aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes design to interfaces, not concrete classes Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "design to interfaces, not concrete classes" Watch "design to interfaces, not concrete classes" New topic
Author

design to interfaces, not concrete classes

John Holme
Ranch Hand

Joined: Oct 11, 2002
Posts: 54
I am reading a very helpful book, J2EE Design and Development, by Rod Johnson (Wrox Press), in which the author refers repeatedly to this concept of designing/coding to interfaces, not concrete classes. However, I can't find anywhere in the book where the author explains in any depth what this actually means.
What Johnson appears to be saying, taken literally, is to provide a java interface for every class in the application. As a novice OO designer, this seems like overkill to me, but maybe that's just my ignorance. On the other hand, maybe he's referring to interfaces in the design process more generally, and is not suggesting an actual java interface for every prospective class. Or, maybe he's only suggesting that developers should begin designing classes by creating an interface-like skeleton that lists methods, but doesn't provide implementations; then fleshing out the implementations when the design process is more advanced.
I'd appreciate hearing anyone's ideas about what Johnson really means by his statement, plus references to any recommended java/oo-design book(s) that might provide a detailed treatment of this subject.
Thanks!
John Holme
B Hayes
Ranch Hand

Joined: Feb 07, 2003
Posts: 61
Hi John,
Check out this article:
http://www.javaworld.com/javaworld/jw-09-2001/jw-0921-interface.html
I'd like to hear your (or any) comments on it.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by John Holme:
What Johnson appears to be saying, taken literally, is to provide a java interface for every class in the application. As a novice OO designer, this seems like overkill to me, but maybe that's just my ignorance.

No, you are correct - it would be overkill.
If you would do it, it would make your code more flexible. That's a nice think. Unfortunately, it can also make your code more complex, so you need to find the balance. (It's almost always a wise choice to code against java.util.List instead of ArrayList, for example.)
A good article on the topic is http://www.objectmentor.com/resources/articles/dip.pdf
I would also highly recommend reading the authors book "Agile Software Development - Principles, Patterns and Practices", where he more extensively explains this and similar principles.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
John Holme
Ranch Hand

Joined: Oct 11, 2002
Posts: 54
Wow! thanks for these excellent references, especially the articles by Wm. Paul Rogers...
Maximize flexibility with interfaces and abstract classes
excellent treatment of using interfaces to define types and abstract classes to define common implementation details.
there's still the trick of figuring out how to apply these concepts to any particular design issue, but this article provides a framework for getting started. definitely helps flesh out the concept of designing to interface, not class. interfaces define types; classes define implementations: keep 'em separate.
As the same author writes in another related article (Thanks type and gentle class), which provides some helpful background to this discussion:
"An understanding of the distinction between type and class facilitates the separation of interface and implementation. When you want to know what an object can do, think type. When you want to know what an object will do, think class."
... and, in another very helpful article (Reveal the magic behind subtype polymorphism) which emphasizes the importance of the type of a given reference to an object, as opposed to the actual type of the object itself, including more very revealing diagrams:
"Types determine what methods the object may perform; implementation determines how the object actually responds to each method. That is, types declare responsibilities, and classes implement those responsibilities."
I now have the motivation I need to start the type hierarchy of major business objects (User, Product, Invoice, Payment Method, etc.) with an interface (with the first level of implementation being an abstract class). This is a big step beyond where I was before reading these articles!
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
It's certainly quite helpfull to think about types and classes as separate concepts. I doubt, though, that it's always the best approach to also separate their representations in code. In many cases it's quite reasonable to let a class represent its type, too.
An interface is of big value when you need to vary the implementation. It's also a good idea to use interfaces in your published API - you will be thankfull for every bit of flexibility you can get in redesigning your API while it's already in use.
The overuse of interfaces, on the other hand, can also lead to code that is harder to understand than necessary. A type that has only one implementation and isn't used outside your team might not justify the existence of its own interface. Especially as with modern refactoring tools it's rather easy to introduce it later in development, should you begin to feel the need.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
My team is starting design on a system that we'd like to have support plug-in product lines. That is, we want to add a product line without opening up, modifying, building, testing, debugging and deploying the core of the system. So the core cannot have any references to concrete classes for product lines we haven't even thought up yet. Instead the core "owns" interfaces which the product lines must implement. Then we can pass new product classes through the core, the core can call required methods. Is that a useful example?
BTW: Another vote for Uncle Bob's Agile Software Development. Here's an (edited) presentation I did for my team that borrows heavily from it: http://www.surfscranton.com/architecture/DependencyInversion.htm


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
John Holme
Ranch Hand

Joined: Oct 11, 2002
Posts: 54
very useful example, Stan, and very worthwhile presentation. I like the way your presentation adds requirements and then models alternative ways of dealing with the new requirements.
one very basic part of the challenge I'm facing as a sort of one-man band in my workplace is to model the basic business process in a way that is extensible. for example, I started out with a CreditCard object, but then realized I better make that a PaymentMethod object in case someone wants to add Paypal or purchase orders. additionally, I've got a User object which can be subclassed as a Customer object which can be subclassed as either a Downloader (1-off purchase/payment) or a Subscriber (recurring payment for ongoing service).
thanks for your help,
John Holme
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
A couple things ... consider starting with an interface for PaymentMethod. Does the base class have very much behavior? If so it might be worth having, but make sure it is abstract.
Customer sounds a little dangerous here. What happens when a customer changes from Downloader to Subscriber? You can't change the type of an object in memory. You could create a Subscriber, copy all the customer data into the new object and discard the old object, but others might have pointers to it. Yikes!
What do subscriber and downloader both do? Make payments, have paid-up status or some amount on account. (I'm making stuff up here ... might not even be close.) If you can find common methods (say payForService()) put them in an interface and have customer implement the interface. Within the method, customer can delegate the actual work to special classes for Subscriber and Downloader. If they implement exactly the same interface customer might have one line to call currentPaymentStrategy.payForService(). The GoF pattern name is "strategy" as in "What's my strategy for making payments?" Customer calls its current strategy object that contains the logic. When the customer upgrades from Downloader to Subscriber we plug in a new strategy and the customer.payForService() method has all new logic. Cool.
John Holme
Ranch Hand

Joined: Oct 11, 2002
Posts: 54
actually, the Downloader and the Subscriber both do pretty much the same thing: they pay for a service. the difference is that the Subscriber has agreed to pay again at regular intervals into the future until the app receives a "cancel subscription" message.
maybe the difference is not so much in the type of Customer, but the type of Service they're paying for: recurring instead of one-time. the thing is that a Subscriber can also pay for a one-time Download; the difference between the Subscriber and Downloader in paying for the Download is just that the Subscriber gets a price break.
but it seems like maybe recurrence is a property of the service/product or even the paymentMethod, rather than the Customer.
John Holme
Ranch Hand

Joined: Oct 11, 2002
Posts: 54
wow! I just became a Ranch Hand!
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: design to interfaces, not concrete classes