Mittwoch, 15. Februar 2012

Avoiding Redundancy in Specifications

I have the impression that some colleagues feel a bit strange in certain situations when specifying in interface. And it is the same with me ;). This feeling comes up, when I formulate something in natural language which is obvious from the corresponding identifiers. But the conventions (e.g. the Javadoc Guidelines) force me to do so. Consider the following example:

/**
 * Returns the customer with the given id or <code>null</code>, if
 * no record is found.
 * 
 * @param id
 *            The id to look for
 * @return The found customer or <code>null</code> 
 */
public Customer findCustomerById(Integer id);

This simple example contains a lot of redundant information:
  1. The first part of the introduction sentence (until the conjunction "or") repeats what the identifier of the operation says. 
  2. The second part of this sentence tells something, what is also mentioned in the @return-tag.
  3. And finally the explanation of the parameter id is also obvious, isn't it ;).

I think, this kind of redundancy is real noise (see Bertrand Meier's great essay "On formalism in Specifications" for further reading). It prevents us from reading the new and important information, in this example the null-behaviour. So, what to do?

To answer this question I would like to know which information should be included in the specification. Then I would assign this information to the different parts of the spec (e.g. the @param-tag). To derive such information, I use the approach of thematic grids which is implemented in iDocIt!. I classify the given operation as a "Searching Operation". The corresponding thematic grid asks me to document the following information:

ACTION: What is done?
OBJECT: What is searched?
SOURCE: Where is searched?
PRIMARY KEY: How is the searched OBJECT identified?

Let's answer these questions:

ACTION: Find the customer with the given id
OBJECT: The customer
SOURCE: The database of our customer relationship management system
PRIMARY KEY: Parameter id

From my point of view, the identifier of the operation explains very well what the operation does. And it also contains the searched OBJECT. I think no further comments are needed. But the Javadoc guidelines force us to formulate an introduction sentence explaining what the operation does. I suggest to explain here, where the operation searches (thematic role SOURCE). From my experience it is always a good idea to explain the null-behaviour only in the @param- and @return-tags. This would lead to this refactored version of the specification:

/**
 * The source of the returned customers is the customer relationship 
 * management system operated by the customer care department.
 * 
 * @param id
 *            Primary Key. <code>null</code> is not permitted here.
 * @return The found customer (object) or <code>null</code> 
 */
public Customer findCustomerById(Integer id);

So, I conclude when specifying an interface one should follow these (rough) steps:
  1. Classify the operation and identify which information needs to be documented (e.g. by using the thematic grids of iDocIt!).
  2. Fill the thematic grid precisely.
  3. Identify which information are already expressed by the identifiers oder could be expressed by identifiers. Strike them from the grid and rename the identifiers, if necessary.
  4. Formulate the remaining information as specification, e.g. in Javadoc.
From my experience: for the parameters and return-values there is always the possibility to restrict the set of allowed values. It is also a useful information, if all possible values are allowed (e.g. for an int in Java).

Keine Kommentare:

Kommentar veröffentlichen