code maintenance

22
Code Maintenance: Specification Standards for Class Design Sunday, 4 November 12

Upload: zhichaowang

Post on 12-Nov-2015

223 views

Category:

Documents


1 download

DESCRIPTION

f

TRANSCRIPT

  • 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