Talk:Code Against Interfaces, Not Implementations

From APIDesign

(Difference between revisions)
Jump to: navigation, search
(Usefulness of abstract classes.)
(Maybe a beginner question...: new section)
Line 86: Line 86:
--[[User:JaroslavTulach|JaroslavTulach]] 12:32, 28 January 2009 (UTC)
--[[User:JaroslavTulach|JaroslavTulach]] 12:32, 28 January 2009 (UTC)
 +
 +
== Maybe a beginner question... ==
 +
 +
Hi Jaroslav,
 +
 +
I'm currently reading your very good book and just finished chapter 6... and I'm a bit confused by this chapter.
 +
You say "Code Against Interfaces, Not Implementations", then you recommend not using Java interfaces if I want to add methods later but instead use final classes.
 +
I don't understand how providing final classes in an API is coding against interface: final classes cannot be subclassed by definition, so if you have a final class in your API, you provide an implementation... or did I miss something ?
 +
 +
I used to design my API almost exclusively with Java interfaces. I agree that they are thus not very evolvable... But at least I define the "what" and let the user implement the "how" (most of the time, I provide a default implementation). I have the feeling that according to your advice, I have to provide my users with both the "what" and "how"... and it doesn't feel right...
 +
 +
Kind regards

Revision as of 16:39, 31 August 2010

Done: e368fc1dbe72

The sentence "Imagine that NetBeans had used a different signature for the aforementioned method..." is a bit hard to read, mostly because of "different". Instead, consider something like "If the NetBeans getCause method had been defined with a Throwable return type, it would have ended...".

--AndreiBadea 09:43, 7 April 2008 (UTC)

Done: cd866eaf3b80 - I've explained something but not all the details. Still you need to know at least a bit of knowledge how the VM stores the objects, or you need to trust me that I know.

Your comparison of multiple inheritance and delegation is unclear. Just how could I use delegation instead of multiple inheritance, and why would this require 16 bytes of memory per interface? This needs to be significiantly expanded for clarity.

--AdamDingle 00:38, 13 April 2008 (UTC)

Done: 24bf47daa023

The "public final class InstanceProvider" does not make sense as written. The whole point of InstanceProvider is that it is something that has to be implemented, as well as called. If there were the InstanceProvider and BetterInstanceProvider interfaces as before, and a separate final API class (or static utility methods), the point would be made.

--JesseGlick 00:59, 8 April 2008 (UTC)

Done: a578de6e7ceb agreed but not in such strong way

Static factory methods can be put into a separate noninstantiable class:

public interface Tweeter {
  void tweet();
}
public class Tweeters {
  private Tweeters() {}
  public static Tweeter softTweeter() {...}
  public static Tweeter loadTweeter() {...}
}

so this is no real argument for making Tweeter be an abstract class.

I would offer a grave warning against putting protected abstract methods into an interface. In practice I have usually found such methods to be a mistake. For example, it makes it impossible to create a proxy implementation that just adds some aspect such as logging.

--JesseGlick 01:07, 8 April 2008 (UTC)


Done: f1d73f9490a0

The Request/Response example has a few superfluous usages of this. Or perhaps you prefer to prefix all field references with this -- that's fine, but it should be done consistently.

Page 97, para 1: "trampoline pattern" should probably be "friend accessor pattern".

--AndreiBadea

  • C'mon Andrei, that is an implementation detail, from point of API this does not matter!

--JaroslavTulach 12:31, 7 April 2008 (UTC)

Right, the API couldn't care less. But I believe that if the book isn't polished, its credibility will suffer. I haven't seen much inconsistency in, say, Effective Java.

--AndreiBadea 19:50, 7 April 2008 (UTC)

  • Which is probably because effective java is about coding and not about APIs.

--JaroslavTulach

I would like to second Andrei's point. Even bad indentation in an example in a book greatly diminishes its credibility.

  • Hmm, ok.

There is a minor potential problem with this Request/Response pattern: there is no guarantee that the Compute implementation will not hold onto the Response object after the computeData method is called. The caller should immediately copy the fields out of the Response object to be sure.

  • Solving it is easy - add final close() {...} to Response, but that complicates the example, and anyway belongs more to runtime aspects of an API

--JesseGlick 01:19, 8 April 2008 (UTC)

Usefulness of abstract classes.

on page 95 you ask- are abstract classes useful? Basically, the answer seems to be - not usually. What's not addressed is why the classic purpose of abstract classes- pluggable algorithm implementations - is not seen as useful.

The classic justification for an abstract class is to permit later, presumably better, implementations to be "plugged in" by the developer (API consumer) .

So in the book, you answer the question- can API developers safely add abstract methods (to an existing API ) but then this seems to expand into "are abstract methods ever useful?" and this is confusing me.

Did you mean to say that abstract classes are never useful? Or are you still talking about ADDING an abstract method to a "star" (published API class).

Great book... one of the best I've read, btw.

---

Thanks. I guess you will find answer to your question in chapter 10's Delegation and Composition. The Arithmetica example shows why one shall be aware of subclassable classes in API. As usually (but not always), abstract classes behave like the subclassable ones, one shall be aware of them too.

Also, the chapter 10 also contains an algorithm for converting any subclassable class (which usually has multiple meanings) into three classes and interfaces delegating to each other. I recommend this technique as it helps the API's clarity. I shall blog about this topic, when I find time. Thanks for asking your question.

--JaroslavTulach 12:32, 28 January 2009 (UTC)

Maybe a beginner question...

Hi Jaroslav,

I'm currently reading your very good book and just finished chapter 6... and I'm a bit confused by this chapter. You say "Code Against Interfaces, Not Implementations", then you recommend not using Java interfaces if I want to add methods later but instead use final classes. I don't understand how providing final classes in an API is coding against interface: final classes cannot be subclassed by definition, so if you have a final class in your API, you provide an implementation... or did I miss something ?

I used to design my API almost exclusively with Java interfaces. I agree that they are thus not very evolvable... But at least I define the "what" and let the user implement the "how" (most of the time, I provide a default implementation). I have the feeling that according to your advice, I have to provide my users with both the "what" and "how"... and it doesn't feel right...

Kind regards

Personal tools
buy