i-scream documentation viewer
coding_standards.txt
Coding Standards ================ tdb1, 28/11/20000 Document description ==================== The purpose of this document is to provide a defined standard to which all code will conform. This will ensure consistency across all files, and allow all members of the team to easily follow the different pieces written by other members. Contents ======== - Foreword - Structure & Layout - Identifiers - Final Variables - Indentation and Layout - Bracketing - Exceptions - Access Control - Imports - Overall Class Layout - Naming Conventions - Commenting & Documentation - Class and Interfaces - Methods - Attributes and Variables - General Commenting - General Recommendations - Threading - Class Design - Platform Foreword ======== In constructing this document I have heavily used content found in the following documents. I have tried to use these documents to give our Coding Standard a solid foundation, without doing a lot of unnecessary work that has already been done by these authors. The majority of this document is taken from the book by David Barnes, with the other two just being used for small parts which David hasn't covered in as much detail. Java Stylistic Conventions, by David Barnes http://www.cs.kent.ac.uk/people/staff/djb/Book/style.html Draft Java Coding Standard, by Doug Lea http://g.oswego.edu/dl/html/javaCodingStd.html Netscape's Java Coding Standards Guide http://developer.netscape.com/docs ... ... /technote/java/codestyle.html Structure & Layout ================== Identifiers ----------- Identifiers can come down to simple imagination, and there isn't a right or wrong way of doing it. The only restriction is that they should be descriptive and of a reasonable length. A variable name should have a single use and a name fitting to this use, rather than using a single non-descriptive name for multiple purposes. A common convention is that names of methods, attributes, and variables should begin with an initial lower-case letter and have a single upper-case letter at the start of each new word within the name. Class names should begin with an uppercase letter and follow the same rule for the start of each new word. Examples of these could be: myVariable aClassAttribute aUsefulMethod() CleverClassName Accessor and Mutators should have names based on the attribute to which they provide access. They should begin with the prefix get or set followed by the name of the attribute beginning with a capital letter. For example the variable item would have the following accessor and mutator: getItem() setItem() Variable names with a single character, such as x, should be avoided as they convey little about their use. The only exception to this rule is when it is used as a loop-control variable in a for-loop. In this instance the variable serves only as a counter, and this is obvious from it's use. Method variables are those used within a method and should be used in preference to an attribute if their use is to be short. They should be defined as close to their use as possible to make code easier to follow. Use should be made of the fact that variables defined within nested blocks are only visible within the block of code, and thus is only visible to it's related code. Final Variables --------------- It is important to avoid the use of magic numbers within the code. The main reason for this is that it can be hard to identify which numbers should be changed if the use of the program needs to be altered. Instead a final variable should be defined in the program: private final int ST = 2; private final int E = 3; private final int S = 1; The only time when magic numbers are acceptable is when they are used as a variable initialiser or as a simple step. Sometimes final variables are needed by more than one class, in which case they should be defined as public static final instead. These types of variables with public visibility should be placed at the start of the class definition Final variables should also have all upper-case names, thus making them clearly identifiable over class attributes. The use of the final word will also dictate that they cannot be changed, so accessor's and mutator's are not necessary. Indentation and Layout ---------------------- Lines should be kept to a sensible length to make the code easier to read and print. Lines should be broken at a sensible point and indented further than the current level of identation. If space permits they should be lined up as appropriate with the previous line: private static final byte[] packet = { Datatypes.FLAG, Datatypes.TERM, Datatypes.FLAG, }; Indentation should be four spaces for each level, and single blank lines should be used to separate methods and to emphasize blocks of code, as in this example: class MyExample { public int returnValue(int x){ return x; } } Methods should be defined first in a class, preferably in order of visibility - public methods first, private ones after. Attributes should be defined after methods for the class, exception for public final variables which should be defined first. This will be discussed further in Overall Class Layout later on in this document. Bracketing ---------- Brackets are very common in Java code and can be used sensibly to clearly show the blocks of code they encapsulate. An opening curly bracket that follows a class header should be indented by a single space, but those used after a method header should not. Closing curly brackets should be placed on the line after the last line of the code they enclose, at the same level of indentation as the start of the header on which the block begins: class MyExample { public void method(){ . . . } } Curly brackets should always be used for if-, while- and for-, even when not strictly needed - such as when the body only contains a single statement. This is the correct way to do it: if(x > largest){ largest = x; } Sometimes statements within normal brackets need to be broken across several lines. This break should occur after an operator and the next line should be indented further than the code which will follow in the body. Exceptions ---------- Exceptions should be used where necessary, and these should almost always be checked exceptions. Instead of throwing the basic Exception classes, sub-classes should be made with more meaningful names, although they need not provide any further functionality. Appropriate catch statements should be put in place to allow the program to recover if need be. Access Control -------------- The following rules should be adhered to, ensuring that access control is correctly implemented and used. - Attributes of an object should be declared as private, rather than public, package or protected. The only exception is in the use of static final variables which cannot be changed anyway. - Accessors may be used to grant access to attributes of a primitive type, although much more care must be taken when returning references to attributes of object types since this could lead to possible bypassing of any mutators. - Mutators should be protected unless they specifically need to be public. A mutator can ensure that values are checked before being put in to the private attribute. - Methods commonly have public access, although private access should be considered if the method is to be used only by the class in which it is placed. - Package visibility should also be considered if the use of packages is implemented. Again, each method's use should be considered carefully, and an appropriate access control method chosen. - Protected visibility is unlikely to be used as sub- classing any of the classes is unlikely, although if such a situation should arise it should be carefully considered. When considering what type of access control to use it is best to be more restrictive than lenient. If a method's visibility is too restrictive then it will be identified more quickly than if the reverse were to happen. Imports ------- The use if the * form of import should be avoided. Each class should be specifically imported as required, and any unused imports should be removed if they are no longer needed. This makes it clear as to exactly what the class is using. Overall Class Layout -------------------- The overall layout of a class is important, especially when it comes to reviewing the code at a later stage. Here I will outline the order in which methods and attributes should appear in a class. This psuedo class shows where everything should appear, including imports and package declarations. Commenting will be dealt with in a further section. // package declaration package server // imports import java.util.LinkedList import java.io.InputStream class MyDummyClass { // attributes such as "magic numbers" should be first public static final int S = 1; public static final int E = 3; // no-args constructor first public MyDummyClass(){ . . . } // further constructors follow public MyDummyClass(int x){ . . . } // public methods public void myMethod(){ . . . } // private methods private void anotherMethod(){ . . . } // accessors & mutators public int getMyVar(){ . . . } // private attributes private int myVar = 5; } This layout should be followed in every source file generated. The reason for this structure is that reading downwards you reach the most used methods and attributes first. The exception are the public static final attributes which are put first to allow them to easily be identified and changed at a later date. Naming Conventions ------------------ Although this section has been covered throughout the last section, I think it is key that the various naming conventions be clearly identified here. Examples are given for each convention. - Packages eg. demo.package Package names should all be in lower case. - Files eg. ClassName.java The Java convention is that files have the same name as the class they contain, and the compiler enforces this. - Classes eg. ClassName Class names should begin with a capital letter and each new word within the name should begin with a capital letter. - Exception Classes eg. ClassNameException Exception classes should follow the same rule as normal classes, but should end with the word Exception. - Constants or "magic numbers" (public) eg. MY_STATIC_VARIABLE These public static variables should always be in upper-case. An underscore could be used if required to make the name more readable. - Methods eg. methodName() Methods should begin with a lower case letter and each new word within the name should begin with a capital letter. - Variables and Attributes eg. variableName Both variables and attributes should being with a lower case letter and each new word within the name should begin with a capital letter - exactly the same as methods. - Accessors eg. getVariable() Accessors should follow the same rules as a normal method, but should be named after the variable which they provide access to. - Mutators eg. setVariable(...) Mutators should follow the same rules as a normal method, but should be named after the variable to which they control access. Commenting & Documentation ========================== All programs should be properly and thoroughly documented. The javadoc tool provides a convention for documenting code and facilitates the automatic generation of program documentation. Classes and Interfaces ---------------------- Each class should have a javadoc comment block at the start of the code. This block of comment should be placed in the standard javadoc style /** .. **/ immediately preceding the class header. Package declarations and imports will appear before this initial documentation. Within this section the following items should be included: - Class Name - Description of the class and it's use - Revision History - Author(s) - javadoc tag - Version Number - javadoc tag It is important to note that as well as the code being read by hand, these comments will also be used to generate information about the class on a webpage using javadoc. Bearing this in mind it may be necessary to use HTML tags to layout the comments, although these should be neatly done so as not to make the comments unreadable in the source code. Various javadoc tags should be used to give specific information to the javadoc engine. These should be placed on a separate line. - @author <author name> The name of the author, preferably with e-mail address. - @version <version number> The version number of the code, with date. This is an example of a class header, which contains all of the above items. /** * MyClass <br> * * This class is merely for illustrative purposes. <br> * * Revision History:<br> * 1.1 - Added javadoc headers <br> * 1.0 - Original release<br> * * @author T.D.Bishop * @version 1.1, 19/04/2000 */ public class MyClass { . . . } Methods ------- Methods should contain a similar javadoc comment to classes, which should be places between /** .. **/ marks immediately preceding the method header. It may not be necessary to do this for all methods, but constructors and major methods certainly should have them, whilst accessors and mutators can have a more cut down version. The following items should be included: - Purpose of method - Argument descriptions - Result descriptions - Exceptions thrown There are also javadoc tags that can be used specifically for method comments. In a similar way to class comments each begins with an @ and should be placed on a line of it's own. - @param <param name> <param description> Should be specified for each parameter that a method takes, with it's name and purpose. - @return <description> Describes the result returned by the method. - @throws <exception name> <reason for being thrown> Gives the name of any exceptions that may be thrown, and why. Here is an example of a method header, showing the above in use. /** * This method has no use, and it just illustrative. <br> * Although it does suggest adding the two parameters * together ! <br> * * @param first The first number to be added * @param second The second number to be added * @return The sum of the two parameters * @throws BadException if something goes very wrong ! */ public int sumNumbers(int first, int second) throws BadException{ . . . } Attributes and Variables ------------------------ Attributes and variables require far less commenting than classes and methods. They should simply contain a brief description of what they are used for, and could possibly refer to any accessors or mutators that allow access to them. Attributes that are public static final should have a bit more detailed information as other classes may wish to use them. Here is a basic example: /** * This attribute represents the byte value used to start * a packet. */ public static final int ST = 2; General Commenting ------------------ It is often necessary to add comments within the body of a method. It is preferable to comment in blocks, rather than individually on each line. Likewise it is not necessary to comment code that is obvious in it's purpose. Both single line comments (using //) and multi-line comments (using /* .. */) are acceptable. This is an example of the layout of the two methods: int index = 1; // index of starting point /* This is a mult-line * comment, and spans * several lines ! */ General Recommendations ======================= Threading --------- Threading is a complicated issue, so I will only briefly mention it. The main issue is using the synchronized modifier to prevent deadlock over the system when accessing shared objects. It is important not to overuse this, as it can cause unnecessary deadlock. Use it only when there is a clear need to do so. Class Design ------------ Class design should be done in a way that reduces coupling as far as possible. Simply dividing the overall system into clear defined parts is a good way to start this. Platform -------- This document refers to the Java 2 platform (or JDK 1.2). Everything mentioned in this document is based upon this platform and may therefore be out of date in future versions of the Java platform.