The Artima Developer Community
Sponsored Link

Weblogs Forum
Java API Design Guidelines

34 replies on 3 pages. Most recent reply: Jan 5, 2006 5:32 PM by Geek Alot

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 34 replies on 3 pages [ « | 1 2 3 | » ]
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: No! Posted: Dec 29, 2005 3:07 PM
Reply to this message Reply
Advertisement
> > One of the issues that Eamonn brings up and which I am
> > currently studying is the fact that interfaces are
> > under-specified:
> have you checked out
> http://research.microsoft.com/specsharp/ and
> http://www.jot.fm/issues/issue_2004_06/article2/article2.pd
> f
> ?

Thanks for the links, I'll look into Spec# in more detail. On a quick scan it appears to be similar to Eiffel and D, is that accurate?

> One idea I really like is to use those contracts to verify
> the code - maybe these contracts can even make unit tests
> obsolete.

The only challenge with contract verification, is that there isn't really any way to assure that control paths are executed, they simply verify that if a control path is executed then the preconditions and postconditions of the functions along the way are satisfied. So IMO they are an excellent compliment to unit testing, but not a complete replacement. However I beleive that extensive usage of contract verification, can significantly reduce the need for unit tests.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Missed one Posted: Dec 29, 2005 4:01 PM
Reply to this message Reply
Howabout you toss in "Be consistent with names and concepts"?

Because Java isn't at all.

Why isn't StringBuffer a Collection?
Why doesn't StringBuffer implement the whole String interface?
Why is it array.length, collection.size(), string.length(), and java.swing.List.listSize()?

These are all very well known examples of crummy api design.

Gregor Zeitlinger

Posts: 108
Nickname: gregor
Registered: Aug, 2005

Re: No! Posted: Dec 29, 2005 4:56 PM
Reply to this message Reply
> Thanks for the links, I'll look into Spec# in more detail.
I just found the slides that I read about Spec#:
http://research.microsoft.com/specsharp/FM2005.ppt
They explain both how the contracts and the verifier (Boogie) works.

> On a quick scan it appears to be similar to Eiffel and D,
> is that accurate?
I know too little to tell.

> The only challenge with contract verification, is that
> there isn't really any way to assure that control paths
> are executed, they simply verify that if a control path is
> executed then the preconditions and postconditions of the
> functions along the way are satisfied.
So you are saying that I cannot find dead code?

Gregor Zeitlinger

Posts: 108
Nickname: gregor
Registered: Aug, 2005

Re: No! Posted: Dec 29, 2005 5:19 PM
Reply to this message Reply
> I'll look into Spec# in more detail.
some features:
1) invariants: you say what you modify instead of saying what do don't modify
In the code, you have to mark blocks where the invariants do not hold (because you update fields). This works like the Java synchronized(this) {..}: expose(this) {..}

2) non-null types: imNeverNull!
they are flow-sensitive:
void Foo(T o) {
if (o != null)
T! p = o; // OK!
}

Joshua Bloch

Posts: 2
Nickname: jbloch
Registered: Dec, 2005

Re: Java API Design Guidelines Posted: Dec 29, 2005 5:36 PM
Reply to this message Reply
Hi. Thanks for the kind words! I have a talk on API design that I first wrote as a keynote for OT-2004 (in St. Neots, UK). I have given the talk a number of times since, including the workshop on Library-centric Design at OOPSLA-2005. Here are the slides: http://lcsd05.cs.tamu.edu/slides/keynote.pdf . From the discussion above, it looks like others have come up with many of the same ideas independently.

Regards,

Josh

Jean-Louis Ardoint

Posts: 3
Nickname: jojo
Registered: Jul, 2003

Re: Java API Design Guidelines Posted: Dec 30, 2005 5:43 AM
Reply to this message Reply
These guidelines are very interesting.

Interfaces may be overvalued, yet the arguments are not very convincing. The examples based on String and Integer show that interfaces are not the best for implementing immutable types, but that's about it. Also, String and Integer are not really the typical classes you define when you design an API. For example, I don't think I ever needed to call the String constructor. With Java 5, it seems it is the same with Integer, and that the use of Integer.valueOf(int) is preferred over new Integer(int).

I don't agree with the argument that there is no point in exposing an interface if the user can't provide his own implementation. There are plenty of SPIs that you usually don't need to implement yourself, and this is not a problem.
One of the interest I found in using interfaces (and a factory interface) in a product API is that you can provide different implementations. If you provide classes instead, the user code is filled with new ProvidedClass1 and you will never have the possibility to change the implementation in a later release. If you accept providing interfaces and telling users not to implement it, then the only points against using interfaces are serialization and the missing static methods/constructors.

I would like to have guidelines more closely linked to use cases patterns. In an API, you usually find abstract types implemented as immutable classes (enums for example), domain classes that are usually related (like the car has four wheels) and contain properties of abstract types, utility classes and interfaces, like static utilities or visitor interfaces and implementations.

It seems the question of providing interfaces or classes is mostly interesting for domain classes. If you go for interfaces, then you may wonder whether to separate the interfaces between readonly interfaces and writeonly interfaces... While there is some interest in general guidelines, like the only visible fields whould be static and final, I think it's easier to discuss the merits of each "solution" for a typical use case.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Missed one Posted: Dec 30, 2005 9:32 AM
Reply to this message Reply
> Howabout you toss in "Be consistent with names and
> concepts"?
>
> Because Java isn't at all.
>
> Why isn't StringBuffer a Collection?

Collections hold Objects, StringBuffers hold characters. This distinction is muddled in 1.5 but clear before that.

> Why doesn't StringBuffer implement the whole String
> interface?

String isn't an interface and StringBuffers are not Strings. As of 1.4 a CharSequence interface was introduced which both String and StringBuffer implement.

> Why is it array.length, collection.size(),
> string.length(), and java.swing.List.listSize()?
>
> These are all very well known examples of crummy api
> design.

Different APIs, different developers most likely. It's also well known that the Sun developers write some of the most sloppy code.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Java API Design Guidelines Posted: Dec 30, 2005 9:44 AM
Reply to this message Reply
> The examples based on String and Integer show that
> interfaces are not the best for implementing immutable
> types, but that's about it. Also, String and Integer are
> not really the typical classes you define when you design
> an API.

I agree they are not great examples. Maybe here's a better one. You have an Observable that is not part of the public API. It needs to be informed any time an Object of type A is modified. There is no way for someone outside of the project to develop new A classes properly. Even if they know about the Observable, they can't access it. The other option is to make the Observable public and put directions in the comments about what needs to be done. But this is worse. Now you've not only made the users of your API do all the work, you've made an implementation detail part of the public API and it's going to be next difficult to change later.

> I don't agree with the argument that there is no point in
> exposing an interface if the user can't provide his own
> implementation. There are plenty of SPIs that you usually
> don't need to implement yourself, and this is not a
> problem.

There's a big difference between 'don't need to' and 'can not'.

> One of the interest I found in using interfaces (and a
> factory interface) in a product API is that you can
> provide different implementations. If you provide classes
> instead, the user code is filled with new
> ProvidedClass1
and you will never have the
> possibility to change the implementation in a later
> release.

Look at the GoF AbstractFactory pattern. No interface is required.

> If you accept providing interfaces and telling
> users not to implement it,

You still haven't explained in a convincing manner why there is any value in doing this.

Eamonn McManus

Posts: 20
Nickname: dichotomy
Registered: Apr, 2003

Re: Java API Design Guidelines Posted: Dec 30, 2005 9:45 AM
Reply to this message Reply
Bonjour Jean-Louis,

> Interfaces may be overvalued, yet the arguments are not
> very convincing. The examples based on String and Integer
> show that interfaces are not the best for implementing
> immutable types, but that's about it.

Right. This is a reductio ad absurdum intended to convince people who think that APIs should be expressed entirely in terms of interfaces. Value types are a clear counter-example that everyone ought to be able to agree on, and yet there are plenty of APIs out there that use interfaces to express them.

> One of the interest I found in using interfaces (and a
> factory interface) in a product API is that you can
> provide different implementations. If you provide classes
> instead, the user code is filled with new
> ProvidedClass1
and you will never have the
> possibility to change the implementation in a later
> release.

Your argument applies just as well to abstract classes as to interfaces. The reasons I gave can help to choose between the two, but the ability to provide different implementations does not.

> While there is some interest in general
> guidelines, like the only visible fields whould be
> static and final
, I think it's easier to discuss the
> merits of each "solution" for a typical use case.

It would probably be better, but I'm not sure it would be easier to write such a discussion. :-)

Jean-Louis Ardoint

Posts: 3
Nickname: jojo
Registered: Jul, 2003

Re: Java API Design Guidelines Posted: Dec 30, 2005 2:16 PM
Reply to this message Reply
Dia's Muire duit Eamonn (I hope this really means hello :-)),


>
> > One of the interest I found in using interfaces...
>
> Your argument applies just as well to abstract classes as
> to interfaces. The reasons I gave can help to choose
> between the two, but the ability to provide different
> implementations does not.

I totally agree. I was mistaken by the bunch of arguments against using interfaces. Some of them equally apply to abstract classes (like can be extended by anybody, cannot have constructors or cannot be deserialized without knowledge of the concrete class).

>
> > While there is some interest in general
> > guidelines, like the only visible fields whould be
> > static and final
, I think it's easier to discuss
> the
> > merits of each "solution" for a typical use case.
>
> It would probably be better, but I'm not sure it
> would be easier to write such a discussion. :-)


Indeed, it would be like discovering the right pattern (or idiom) language for designing (Java) APIs. I certainly won't have time to do this before next year ;-).

Happy new year

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Missed one Posted: Dec 30, 2005 6:10 PM
Reply to this message Reply
> > Why isn't StringBuffer a Collection?

> Collections hold Objects, StringBuffers hold characters.
> This distinction is muddled in 1.5 but clear before
> that.

Yes, but you could have an overloaded version of the same api to reduce mindspace clutter. Its still an ordered collection.

Anyhow, that just brings up the foolishness of having primitives in Java. They unnecesssarily clutter the language, it could have been objects all the way down with a little VM smarts. Smalltalk does it and performs about as well.

> > Why doesn't StringBuffer implement the whole String
> > interface?

> String isn't an interface

String has an interface - declared or not.

> and StringBuffers are not
> Strings.

YTF not? They do the same thing - provide an ordered collection of characters. One is mutable, one not.

> As of 1.4 a CharSequence interface was
> introduced which both String and StringBuffer implement.

I think I gave up at that point and moved to Smalltalk. Happy now. Miserable before.

Calum Shaw-Mackay

Posts: 58
Nickname: calum
Registered: Mar, 2004

Re: Missed one Posted: Dec 31, 2005 3:58 AM
Reply to this message Reply
> Yes, but you could have an overloaded version of the same
> api to reduce mindspace clutter. Its still an ordered
> collection.

Perhaps with auto-unboxing, StringBuffer may now move towards Collection.

> Anyhow, that just brings up the foolishness of having
> primitives in Java. They unnecesssarily clutter the
> language, it could have been objects all the way down with
> a little VM smarts. Smalltalk does it and performs about
> as well.
>
> > > Why doesn't StringBuffer implement the whole String
> > > interface?
>
> > String isn't an interface
>
> String has an interface - declared or not.

String having an interface is not the same as it being an interface.....

> > and StringBuffers are not
> > Strings.
>
> YTF not? They do the same thing - provide an ordered
> collection of characters. One is mutable, one not.

Ordered? How? Indexable maybe. A string is a distinct set of characters, a StringBuffer is a container for characters from which you can call Object#toString() to get the contained characters as a distinct set.

Note that is set not Set.

At the lower level, it all comes down to String storage within the VM, strings are stored only once, and characters which comprise the same distinct set are referenced across the VMs lifetime, whereas a mutable set of characters ie StringBuffer is allocated in normal object memory and available to GC. Well more or less

> > As of 1.4 a CharSequence interface was
> > introduced which both String and StringBuffer
> implement.

At least, it's a way to treat two distinctly dissimilar objects (String and StringBuffer),in operation at least, as similar types.

--Calum

Sebastian Kübeck

Posts: 44
Nickname: sebastiank
Registered: Sep, 2005

Seeing it the other way Posted: Jan 1, 2006 4:17 PM
Reply to this message Reply
I think that it is helpful to see it from an other
Standpoint: Why do we consider an API as bad?

1. Too complicated to use. If I need days or weeks
to find out how to use an API, I don't see why
I should use it.

2. Lack of documentation. The best way to document an API
is providing comprehensive examples in how it should be
used.

3. Lack of functionality. If the API doesn't address my
needs and I have to develop clumsy work arounds,
I just waste time.

3. Lack of testability. If I cannot test the code
that calls the API I never know if my code is working
correctly so I have to tolerate bugs in my code even if
the 3rd partiy functionality is working correctly.

4. Insufficient error propagation. If I don't know what
happend behind the scenes and I don't know how to react correctly on errors, I'm forced to use try and error
to find it out.

5. Instable life cycle. If an API or the functionality it exposes changes in such a way that I have to do allot of changes in my code in order to use a new version.

Conclusion:

A good API should make the developer using
it as productive as possible.


Since the offered guilines aren't clearly adressing the
points above. I don't think that they are much
help for API developers, although there are some good
points also.

Sebastian

Terje Slettebø

Posts: 205
Nickname: tslettebo
Registered: Jun, 2004

Re: Java API Design Guidelines Posted: Jan 1, 2006 6:21 PM
Reply to this message Reply
"API" is a pretty general term, but as it says "Java API", I assume that the guidelines are about _library design_.

I think there's not that much difference between application design and library design. In a well-written application, you typically have layers, and some of it may be third-party components.

A good way to design something, whether it's application code or library code (if you can make a distiction between them), is to do "Domain-Driven Design" (http://domaindrivendesign.org). In my opinion, there's surprisingly little written about this important subject, and the book by the same name is one of the best I've ever read (I'm not saying that lightly, I've read many books about all aspects of software development).

In DDD, the focus is on expressing the "domain model" in the system. A good library could present a coherent domain model, making it both easier to learn and use, and also more powerful (than one without it).

Guidelines, such as "Shouldn't be too complicated", or "Should have enough functionality" (from a recent posting) has limited value, in my opinion. It's almost like saying you should "write good code". Sure, but how? DDD provides an answer.

Terje Slettebø

Posts: 205
Nickname: tslettebo
Registered: Jun, 2004

Re: Java API Design Guidelines Posted: Jan 1, 2006 6:38 PM
Reply to this message Reply
Another guideline on library/framework design is to, rather than designing one up-front, you factor it out of several applications. However, this one may be difficult to follow in practice, as it requires existing applications. It has interesting intersections with TDD (where you have an "existing application" (a test) before you write the code) and DDD (you may have been able to come up with a good domain model, through the development of the applications, due to "refactoring towards deeper insight" (a term from the book), i.e. refactoring an application to make it aligned with a domain model (as the model and code is developed and refined)).

Flat View: This topic has 34 replies on 3 pages [ « | 1  2  3 | » ]
Topic: Mixins2 Previous Topic   Next Topic Topic: Mixins: Something Else You Can't Do With Java Generics?


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us