Tuesday, November 04, 2008

Java Coding Convention

=== WHAT ===

Coding convention (quy ước viết mã) : set of conventions (recommendations) for naming, formatting, and documentation requirements.

Coding standard of XYZ (chuẩn viết mã của XYZ) : set of standards (rules) of XYZ for naming, formatting, and documentation requirements.

Coding style (phong cách viết mã): the way somebody writes code and layouts. To get more effective and productive when programming, we should have common coding style and good practices; therefore we should follow practical coding conventions or coding standards.




=== WHY ===

The first and most important reason is Readablity (and reusability, of course) : easier for developers to read and understand each other's code . As a result:


+ Quicker adapt to source code of new project, regardless of debugging/testing/coding


+ Quicker transfer knowledge across projects, very useful for newcomers


And also the conventions can reduce name confliction, make better proliferation (e.g. pointTotal, totalPoints), emphasize relationship among related items (e.g. Customer { customerName, customerAddress, ... } ) , and compensate for language's weakness‏es .




=== WHEN ===

+ Multiple developers are working on a project.

+ Your program is so large that you can't hold the whole thing in your brain at once and must think about it in pieces.

+ The program will be long-lived enough that you might put it aside for a few weeks or months before working on it again.

+ Plan to turn a program over to another programmer for modifications and maintenance (which is nearly always).

+ Your programs are reviewed by other programmers in your organization.




=== HOW ===

Here are some recommended coding conventions for Java, yet it can be applied for other popular programming languages (PHP, ActionScript, Ruby, ...) , with a slight modification.


+ File name: should be alphanumeric (to be exact: [A-Za-z][A-Za-z0-9] ) and underscore ( _ ) , hyphen ( - ) , dot ( . ) only . Fortunately the Java compiler requires ".java" as an extension , and it will produce ".class" byte code file, so we can prevent some sudden inspiration with file names :D .


+ File organization: In a file, we should use blank lines to separate sections, make it clean and clear. Usually 1 or 2 blank lines is sufficient, depends on how "big" that section is. In some extreme case we can use 3 blank lines to separate. Note that in modern languages such as Java we can alway separate a big program into at least several classes (and corresponding files) , so a file with more than 2000 lines is cumbersome and should be divided (to conquer) !


+ File sections: should be the following order: header comments, package declaration, import declaration, main class/interface, internal classes (if exists). Example:

/*
* @(#)MyClass.java 1.54, 2008 Jan 01
*
* Copyleft 2008 Mediocre-Ninja. Use is subject to license terms.
*/
package org.opensource;

import java.io.Serializable;

/**
* This is the dummy class for demonstration.
*
* @author Mediocre-Ninja
* @author unascribed
* @since 2008 Jan
*/
public class MyClass {
//...
}

class MyInternalClass {
//...
}



+ Class (or interface) declaration: should be the following order

- Class or interface statement

- Class or interface implementation comment, if necessary

- Class (static) fields: public, protected, private

- Instance fields: public, protected, private

- Constructors.

- Method: grouped by functionality rather than by scope


+ Indentation, line length and breaks: as following

- A tab width is considered "indentation unit", but replace the tab character by 2-4 spaces. [CONTROVERSIAL] The concrete number of spaces depends on the project. Usually 4 spaces for Java/JavaScript, 3 spaces for ActionScript/MXML/XML, 2 spaces for Python/Ruby/Perl/C...

- Try to avoid lines longer than 80 characters, since they’re not handled well by many terminals and tools.

- Principles when breaking lines: break AFTER A COMMA, break BEFORE AN OPERATOR, align the broken line as the same indentation (if it leads to confusing code then use 1 more "indentation unit", i.e. total 2 "units")

- Example:

longNameResult = longName2 * (longName3 + longName4 - longName5)
+ 4 * longname6;

var = someMethod1(longExpressionHere,
someMethod2(longExpressionAgain,
longExpressionYetAnother));

if ( (condition1 && condition2) || (condition3 && condition4)
|| !(condition5 && condition6) ) {
doSomethingAboutIt();
}

private static synchronized horkingLongMethodName(int anArg,
Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
//...
}

alphaResult = (aLongBooleanExpressionForTernaryOne)
? betaValueHere
: gammaExpressionHere;



+ Comments: in Java can be classified as 2 kinds: Documentation (javadoc) comments, and implementation comments (both block comment (C-style) and line comment (C++ style) ).

- trailing comments should be seperate (i.e. at least 1 space) from the semi-colon or left-most character

- non-trailing comments should be preceded by a blank line

- summary points should be in uppercase. Example: // TO DO: , // FIX ME:


+ Naming convention:

- packages: use lowercase, group by function rather than scope

- classes: should be nouns, in mixed case with the first letter of each internal word capitalized. Also known as "PascalCase" or "UpperCamelCase"

- interfaces: like classes

- constants: should be all uppercase with words separated by underscores ("_").

- methods: should describe actions or states, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized. Also known as "camelCase" or "lowerCamelCase" . [CONTROLVERSIAL] Use strict camelCase (either UpperCamel or lowerCamel) for abbreviations.

- variables: should be nouns, short yet meaningful, capitalized as "camelCase" . Should not start with '$' dollar-sign. [CONTROVERSIAL] To distinguish fields and other variables, use 1 underscore '_' as prefix for field names. [CONTROVERSIAL] To distinguish method parameters and other variables, use 1 underscore '_' as postfix for method parameters. [CONTROVERSIAL] Should not use "Hungarian" notation, use "postfix Object" instead. Example:

//import done
public class MyObject {

private String _objectName;

public String setObjectName(String objectName_) {
this._objectName = objectName_ ;
}

protected String downloadXmlThroughHttp(String xmlFileName_, URL httpUrl) {
//...
}

public static void main(String[] args_) {

public String objectName ; // don't use "strObjectName"
public String myMessage = args_[0]; // don't use "strMsg"

JTextArea commentTextArea; // don't use "txtComment"
protected JButton cancelButton; // don't use "btnCancel"
protected JButton saveButton; // don't use "btnSave"

private DataInputStream myDataIS; // don't use "dis"
private BufferedOutputStream myBufferedOS; // don't use "bufferedOutputStream"

//...
}
}



+ Miscellaneous recommendations:

- [CONTROVERSIAL] Open brace '{' appears at the end of the same line as the declaration statement. Also known as "one true brace" .

- Each line should contain one statement, at most.

- Use braces for single-statement block (if, else, do, while, for, try, catch,... )

- Always have 1 space (at least) to seperate operator, casting, parameters from others.

- No space between a method name and the parenthesis '(' which starts the parameter list

- Try to initialize local variables where they’re declared




=== Reference ===

+ Ontko's Java coding standard collections (including Sun's, Dough Lea's, ...)

+ Agile Java Development book, Appendix B

+ Java Power Tools book, part 6

No comments: