views:

61

answers:

4

I have a question about where to document logic in javadocs. For example, I have the following method signature in an interface:

public int getTotalAssociationsAsParent(Long id, Long type);

The method returns associations where the given ID is the parent and the association is of type 'type'. ID is required, but if type passed in is NULL, then I will return ALL associations where the ID is the parent.

My question is where should this type of logic be documented? I hesitate putting it in the javadoc of the interface because that sort of constrains all implementing classes to adhere to that logic. Maybe in the future, I'll have an Impl class that throws an IllegalArgumentException if type is NULL.

However, if I put it in non-javadoc in the Impl class, then consumers of this method won't know how the method behaves with a NULL type.

+3  A: 

What you describe is the interface contract of the method, so it belongs to the Javadoc indeed. Clients of the interface need to know the exact contract this interface fulfills. If a derived class implements the method differently, it effectively breaks the contract, thus breaks the Liskov Substitution Principle.

However, if you feel there really is place for different implementations of this method, you have some choices:

  • rethink your design - maybe those implementations should not be in subclasses of the same interface, or maybe you need two distinct methods in that interface
  • define the contract loosely to allow some variance in implementation (but only if it makes sense from the clients' perspective!)
Péter Török
Thank you for the advice (everyone). I think what I need to do is put this in the javadoc of the interface and define what this method should do. If it ever comes to pass that I do need a method that returns ALL associations, I simply create:public int getTotalAssociationsAsParent(Long id);It should be noted that this isn't even a requirement anyway, so I should be following the YAGNI principle here.
A: 

You should describe what it will return to the client in what case. The client does not need to know about how you process to return it but it should know with some kinds of input, some special output will be returned.

In the future, if you want to throw an exception, you have to change your javadoc so that the caller can know it has to handle an exception

vodkhang
A: 

In general you put this on the interface, the interface defines the behaviour of the implementations. However there is no hard and fast rule here, if a particular implementation behaves differently you can also put that difference on the implementation comment. This is very similar to how the Java Standard Library does things in their JavaDoc.

Consider, for example, ArrayList:

http://java.sun.com/javase/6/docs/api/java/util/ArrayList.html

has removeAll, which is defined in List and implemented in AbstractCollection

http://java.sun.com/javase/6/docs/api/java/util/List.html#removeAll(java.util.Collection)

http://java.sun.com/javase/6/docs/api/java/util/AbstractCollection.html#removeAll(java.util.Collection)

The List class defines what it does, the AbstractCollection class defines it's particular behaviour.

Docs are a tool, so use them as you feel fit, the most important part of this tool is that they're kept current - so over documenting can cause headaches later, under documenting too! In general also try to keep the code you write in each method short and concise and as free of side effects as possible, this way you're able to read the code and understand what it means to do without so much dependance on the surrounding documentation.

Mike
A: 

Looks perfect for Javadoc:

/**
 * The method returns associations where the given ID is the parent and the association is of type 'type'. <br>
 * ID is required, but if type passed in is NULL, then I will return ALL associations where the ID is the parent.<br>
 *<br>
 * Subclasses may  throw an IllegalArgumentException if type is NULL.<br>
 * @param id Parent identifier
 * @param type the type of association
 * @return the Association or null if type is null
 */
public int getTotalAssociationsAsParent(Long id, Long type)

I wish to have had this kind of doc in the past my self.

I usually get:

/**
 * get the total associations as parent 
 * @param id the id
 * @type the type
 */ 
public int getTotalAssociationsAsParent(Long id, Long type);

Which is not useful.

OscarRyz