• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

design to interfaces, not concrete classes

 
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
John Holme
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
John Holme
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
wow! I just became a Ranch Hand!
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic