code maintenance
DESCRIPTION
fTRANSCRIPT
-
Code Maintenance:Specification Standards for Class Design
Sunday, 4 November 12
-
Specification Standards for Class Design
4 suggested standards which taken together can make your code:
readable maintainable robust
and can help you with the code design
Sunday, 4 November 12
-
1. Use Full Javadoc Standards in Code Comments
javadoc can automatically generate API documentation from documentation comments within your code
you can add special comments to your code delimited by /** */ those comments are processed by the javadoc tool to generate
the API docs
can access javadoc program from command line or within Eclipse
the comments should contain 2 parts, in order: description block tags
Sunday, 4 November 12
-
Example
/**
* Returns an Image object that can then be painted on the screen.
* The url argument must specify an absolute {@link URL}. The name
* argument is a specifier that is relative to the url argument.
*
* This method always returns immediately, whether or not the
* image exists. When this applet attempts to draw the image on
* the screen, the data will be loaded. The graphics primitives
* that draw the image will incrementally paint on the screen.
*
* @param url an absolute URL giving the base location of the image
* @param name the location of the image, relative to the url argument
* @return the image at the specified URL
* @see Image
*/
public Image getImage(URL url, String name) {
try {
return getImage(new URL(url, name));
} catch (MalformedURLException e) {
return null;
}
}
getImagepublicImagegetImage(URLurl, Stringname)Returns an Image object that can then be painted on the screen. The url argument must specify an absolute URL. The name argument is a specifier that is relative to the url argument.
This method always returns immediately, whether or not the image exists. When this applet attempts to draw the image on the screen, the data will be loaded. The graphics primitives that draw the image will incrementally paint on the screen.
Parameters:url - an absolute URL giving the base location of the image.name - the location of the image, relative to the url argument.Returns:the image at the specified URL.See Also:Image
from http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html
description
block tags
Sunday, 4 November 12
-
Quick Guide to Style
can use phrases instead of complete sentences for brevity
use 3rd rather than 2nd person: avoid 'get the label' prefer 'gets the label'
begin method descriptions with a verb phrase: avoid 'this method gets the label of this button' prefer 'gets the label of this button'
Sunday, 4 November 12
-
Quick Guide to Style
for class/interface/field descriptions omit the object and just state subject: avoid 'this field is a button label' prefer 'a button label'
use this instead of the: avoid 'gets the id of the object' prefer 'gets the id of this object'
avoid Latin: avoid 'i.e', 'e.g', 'viz' prefer 'to be specific', 'for example', 'in other words'
Sunday, 4 November 12
-
Quick Guide to the Block Tags
most useful, in order: @author
classes and interfaces only @version
classes and interfaces only @param
methods & constructors only @return
methods only @throws
methods only
Sunday, 4 November 12
-
Quick Guide to the Block Tags
@author not required but useful for teamwork @author jimmyNail
@version of java for which this was written @version 1.6
@param for each data type give the name (not type) and description @param height the height of the door, measured in
millimetres
@return just like @param, can omit for constructors and void returns @throws
include for checked exceptions (declared in the throws clause)
@throws FileNotFoundException if the filename passed cannot be resolved to a valid file path
Sunday, 4 November 12
-
2. Use Total Procedures in Class Design
problem: often the legal set of inputs for a method is smaller than the
possible set of inputs that a client can pass to it
for example:
a squareRoot( double value) method requires an input value 0
solution: we can specify total procedures (or from now on methods)
which specify each type of valid and non-valid input and how it is handled
Sunday, 4 November 12
-
@requires
for each input parameter (@param) in the javadoc we can add a @requires clause
this specifies the validity of the input from the method's perspective for squareRoot():
@param value the number whose square root will be returned
@requires value 0
this lets the reader know that they should not pass a negative value to this method
and we can go through every parameter of every method and identify what the method requires as valid input
Sunday, 4 November 12
-
Minimising the use of @requires
@requires tells us what the legal input is for a method, but it doesn't tell us what will happen if illegal input is passed
for example, if we attempt squareRoot( -1) it's also not part of javadoc
so our aim is not to fill classes with lines of @requires specifications but instead to minimise the need for @requires in the first place
"prevention is better than cure" we can minimise the need in 2 ways:
use crafted types for the input parameters which are always valid for example, instead of squareRoot( double value) use squareRoot( PositiveNumber value)
use or create exceptions to handle non-valid input...
Sunday, 4 November 12
-
Using Exceptions
if the client tries to pass a negative value to squareRoot() then an IllegalArgumentException will be generated
problem: unless the client catches and handles this exception, the
program will crash
solution: place the call to squareRoot() in a try-catch block:
try { squareRoot( value); }
catch ( IllegalArgumentException iaEx )
{ // appropriate reaction goes here }
Sunday, 4 November 12
-
Creating Exceptions
problem: using a try-catch block to handle a generic exception
is better than not handing it
but handling the exception is still optional if we are lazy or forget to code for it, then the
exception can still cause a crash
solution: extend the generic exception with a tailored exception
Sunday, 4 November 12
-
Example: NegativeNumberException
we have replaced IllegalArgumentException with a new NegativeNumberException the exception is explicitly thrown by the squareRoot() method so the client code is forced to explicitly handle it
public class NegativeNumberException extends IllegalArgumentException{ public NegativeNumberException( double value) { super( value); }}
public double SquareRoot( double value) throws NegativeNumberException{ if ( value < 0 ) { throw new NegativeNumberException( value); } ...}
Sunday, 4 November 12
-
3. List all exceptions
list in the methods documentation comments specify using the @throws tag, one for each checked exception and its cause if:
the method is a worker method (private), or the input which generates the exception is extremely unlikely
then consider skipping this activity example:
/** * @throws NegativeNumberException if value < 0 */public double squareRoot( double value) { // method body}
Sunday, 4 November 12
-
4. Use Exceptions rather than Special Return Values
sometimes the method cannot provide a valid return for the given input for example:
suppose an ArrayList of names a getIndex(String name) method which returns the position in the list for a
given name
"Claire" is not in the list a client might call getIndex( "Claire");
it's tempting to add code to getIndex() to return a special value when this happens: if ( !list.contains( name) ) { return -1 }; and then let the client handle this special return value
we've probably all done something like that before
Sunday, 4 November 12
-
4. Use Exceptions rather than Special Return Values
problems with using special values: the client has to know about the special value(s) the client must contain code for handling special values the client code for handling special value(s) might not be obvious
as such, unless we add lots of code comments
a change to the special value(s) will break the client code
solution: use a tailored exception and throw it instead of returning a special
value
Sunday, 4 November 12
-
Example: getIndex()
method: public int getIndex( String name) { if ( !list.contains( name) ) { return -1 }; }
client: int index = getIndex( name); if ( index == -1 ) { // appropriate reaction goes here }
Beforemethod: public int getIndex( String name) throws
NameNotInListException { ... if ( !list.contains( name) ) { throw new
NameNotInListException( String name) }; }
client: try { int index = getIndex( name); } catch ( NameNotInListException nnilEx ) { // appropriate reaction goes here }
After
the method and client code will need code comments to explain the special value and its handling the handling will not be enforced in the specification
might get forgotten in future re-use
the code is now largely self explanatory the handling of the exception is enforced
now and in future
Sunday, 4 November 12
-
Benefits of Standards
creating full javadoc specification: makes you think carefully about where responsibilities should lie increases the likelihood of correct implementation of design increases maintainability
specifying total methods and listing all exceptions: reduces the chance of runtime errors bad input is handled by design increases system reliability assists in testing and debugging
thrown exceptions will state where they originated
Sunday, 4 November 12
-
Benefits of Standards
avoiding Special Return Values: ensures the client takes appropriate action when a
valid return cannot be made
increases reliability reduces the likelihood of runtime errors increases the likelihood of compilation errors but this is good, because to fix the errors we have
to make our code meet the specification
Sunday, 4 November 12
-
To conclude
implementing these standards in full adds a lot of time and effort to a build
so it's not worth it for every project, every class or every method
but where: a method is likely to be broken by bad input, or client code is likely to be broken by a bad return
then consider this approach
Sunday, 4 November 12
-
References & Further Reading
total procedures, special values: Program Development in Java, Liskov & Guttag (2000),
Chapters 3 to 6
javadoc: http://www.oracle.com/technetwork/java/javase/
documentation/index-137868.html
Sunday, 4 November 12