8

Whenever I have the need to design an API in Java, I normally start off by opening up my IDE, and creating the packages, classes and interfaces. The method implementations are all dummy, but the javadocs are detailed.

Is this the best way to go about things? I am beginning to feel that the API documentation should be the first to be churned out - even before the first .java file is written up. This has few advantages:

  1. The API designer can complete the design & specification and then split up the implementation among several implementors.
  2. More flexible - change in design does not require one to bounce around among java files looking for the place to edit the javadoc comment.

Are there others who share this opinion? And if so, how do you go about starting off with the API design?

Further, are there any tools out there which might help? Probably even some sort of annotation-based tool which generates documentation and then the skeleton source (kind of like model-to-code generators)? I came across Eclipse PDE API tooling - but this is specific to Eclipse plugin projects. I did not find anything more generic.

curioustechizen
  • 10,572
  • 10
  • 61
  • 110

5 Answers5

4

For an API (and for many types of problems IMO), a top-down approach for problem partitioning and analysis is the way to go.

However (and this is just my 2c based on my own personal experience, so take it with a grain of salt), focusing on the Javadoc part of it is a good thing to do, but that is still not sufficient, and cannot reliably be the starting point. In fact, that is very implementation oriented. So what happened to the design, the modeling and reasoning that should take place before that (however brief that might be)?

You have to do some sort of modeling to identify the entities (the nouns, roles and verbs) that make up your API. And no matter how "agile" one would like to be, such things cannot be prototyped without having a clear picture of the problem statement (even if it is just a 10K foot view of it.)

The best starting point is to specify what you are trying to implement, or more precisely, what type of problems your API is trying to address. BDD might be of help (more of that below). That is, what is it that your API will provide (datum elements), and to whom, performing what actions (the verbs) and under what conditions (the context). That leads then to identify what entities provide these things and under what roles (interfaces, specifically interfaces with a single, clear role or function, not as catch-all bags of methods). That leads to an analysis on how they are orchestrated together (inheritance, composition, delegation, etc.)

Once you have that, then you might be in a good position to start doing some preliminary Javadoc. Then you can start working on the implementation of those interfaces, of those roles. More Javadoc follows (in addition to other documentation that might not fall within Javadoc .ie. tutorials, how-tos, etc.)

You start your implementation with use cases and verifiable requirements and behavioral descriptions of what each thing should do alone or in collaboration. BDD would be extremely helpful here.

As you work on, you continuously refactor, hopefully by taking some metrics (cyclomatic complexity and some variant of LCOM). These two tell you where you should refactor.

A development of an API should not be inherently different from the development of an application. After all, an API is a utilitarian application for a user (who happens to have a development role.)

As a result, you should not treat API engineering any diferently from general software-intensive application engineering. Use the same practices, tune them according to your needs (which every one who works with software should), and you'll do fine.

Google has been uploading its "Google Tech Talk" video lecture series on youtube for quite some time. One of them is an hour long lecture titled "How To Design A Good API and Why it Matters". You might want to check it out also.

Some links for you that might help:

Google Tech Talk's "Beyond Test Driven Development: Behaviour Driven Development" : http://www.youtube.com/watch?v=XOkHh8zF33o

Behavior Driven Development : http://behaviour-driven.org/

Website Companion to the book "Practical API Design" : http://wiki.apidesign.org/wiki/Main_Page

Going back to the Basics - Structured Design#Cohesion and Coupling : http://en.wikipedia.org/wiki/Structured_Design#Structured_Design

luis.espinal
  • 10,331
  • 6
  • 39
  • 55
  • Thats a wealth of information! Thanks! But you probably misunderstood my "I start off with" statement. Of course the planning and design come first. My question was about getting the documentation out first versus getting the code (interfaces and stuff). Come to think of it, it is the API which is the contract and not the interfaces! If I had to paraphrase my question, I'd ask - is there a way to link javadoc with design (like UML) rather than coupling javadoc with code (at least initially) ? – curioustechizen Aug 05 '11 at 13:32
  • 1
    Hmm, IMO, nope, you cannot link source code documentation to design (let alone the subset of it that is amenable for document compilation). This is just documentation of what "it" is at this particular time, and how to use "it". Source code documentation is as much an implementation output of a design as source code itself is. In fact, I'd argue that such documentation is an integral part of "good" source code and should be seen as integral parts of each other. Think of it this way. Assume all comments in a piece of code are valid and valuable... – luis.espinal Aug 05 '11 at 18:20
  • 1
    con't - It just so happens that not all source code comments makes it to Javadoc. Comments internal to methods documenting internal decisions and which are not mean to explain how to use "it" are not part of the external documentation. Ergo, Javadoc and their equivalent in other language do not provide a complete picture. Also, they do not "model", nor provide a model to reason with. Javadocs explain the utilitarian and configuration aspects of a model (or its concrete system implementation.) It might sound that I'm playing semantics games, but this is a very important distinction. – luis.espinal Aug 05 '11 at 18:24
  • 1
    I'd argue that the API is an implementation of the interfaces, the deliverable itself. There is the contract that shows how make use of this deliverable (the API) independently of whether we provide direct access to it via classes or interfaces (or whether interfaces are being explicit at all). I mean, it's obviously possible to attempt to use Javadocs as the starting design guideline. The question is whether this will be sufficient in the general case (and specially in complex cases.) It's nature as a subset of source code comments, an output of implementation leads me to believe it is not. – luis.espinal Aug 05 '11 at 18:34
  • Or maybe I'm misunderstanding the question. If everything is built properly, everything can be linked to design (and beyond, all the way to valid requirements), and everything can be linked to implementation. At any level, anything must map to something back and forth. I would also say that UML does not link to design. UML is just the language we use to create a UML model that happens to be (or should be) the design itself. The UML model written with UML, when done correctly **IS** the design (and sometimes the architecture.) Javadoc is inherently coupled with Javadoc... – luis.espinal Aug 05 '11 at 18:41
  • 2
    con't - remember, code without javadoc is **bad** code. The presence of Javadoc is necessary but not sufficient for good code (as Javadoc can be useless.) **Good** javadoc (in the company of good code comments that sit outside of javadoc) is still just necessary but not sufficient. However, when you have that in addition to sufficiently correct and sufficiently well-constructed code, then **we have good (or at least good-enough) source code**. And that's one of the ultimate goals. This demonstrates (IMO) that Javadocs are inherently coupled to code (since it is an intrinsic part of it.) – luis.espinal Aug 05 '11 at 18:45
  • 1
    I tend to agree with your view here. Your answer, combined with these comments, sufficiently answer my question. I am thus accepting this answer. And thanks once again for the detailed, argument-backed response :) – curioustechizen Aug 06 '11 at 04:30
3

Defining the interface first is the programming-by-contract style of declaring preconditions, postconditions and invariants. I find it combines well with Test-Driven-Development (TDD), because the invariants and postconditions you write first are the behaviours that your tests can check for.

As an aside, it seems the Behaviour-Driven-Development elaboration of TDD seems to have come about because of programmers who did not habitually think of the interface first.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
2

As for my self, I always prefer starting with writing the interfaces along with their documentation and only then start with the implementation.

In the past I took another approach which was starting with the UML and then using the automatic code generation. The best tool I encountered for this matter was Rational Rose which is not free but I'm sure there are plenty of free plugins and utils. The advantage of Rational Rose over other designers I bumped into was that you can "attach" the design to your code and then modify on either code or design and the other will update.

Lior Ohana
  • 3,467
  • 4
  • 34
  • 49
  • Thanks @LiorO. I have used various plugins for Eclipse and Netbeans that do design-to-code and code-to-design (although I cannot recollect whether any of them were "live" - as in, changing one changes the other). I am looking for a way to extend this notion to API design and javadocs. So, it looks like you start off with the interfaces too. – curioustechizen Aug 05 '11 at 11:07
  • To convert uml to java you also can use MagicDraw. IMHO it's even better than Rational Rose. But it's also not free. – Dainius Aug 05 '11 at 11:21
2

I jump right in with the coding with a prototype. Any required interfaces soon pop out at you and you can mould your proto into a final product. Get feedback along the way from whomever is going to be using your API if you can.

There is no 'best way' of approaching API design, do whatever works for you. Domain knowledge also has a large part to play

James
  • 9,064
  • 3
  • 31
  • 49
  • I agree with both the method and the "do whatever works for you advice": I also like to spend a few hours putting together a prototype and refactoring as bits of unexpected complexity emerge (they always do). After a while it all starts to take shape, and that's the time to start thinking about fixing interfaces, documentation etc. in place - I always find this quicker and more productive than trying to specify interfaces on a blank sheet of paper. – strmqm Aug 05 '11 at 12:24
2

I'm a great fan of programming to the interface. It forms a contract between the implementors and the users of your code. Rather than diving straight into code, I usually start with a basic model of my system (UML diagrams etc, depending on the complexity). Not only does this serve as good documentation, it provides a visual clarification of the system structure. Having this makes the coding part much easier to do. This kind of design documentation also makes it easier to understand the system when you come back to it in 6 months, or try to fix bugs :) Prototyping also has its merits, but be prepared to throw it away and start again.

Andrew Fielden
  • 3,751
  • 3
  • 31
  • 47