Monday, July 4, 2011

Java Coding Standards


1. Introduction
The major objective of this document is to provide standards and guidelines for application developers and designers to develop systems that are maintainable, testable, readable and adaptable to changes in the infrastructure. A system depends on its maintenance instead of development, so it becomes mandatory to write code clean and well packaged. Following are some importance reasons to convey the coding standards during coding phase of project life cycle…
1.     80% of the lifetime cost of a piece of software goes to maintenance
2.     Hardly any software is maintained for its whole life by the original author.
3.     Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.
4.     If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.

This white paper describes a collection of standards, conventions, and guidelines for writing solid Java code. They are based on sound, proven software engineering principles that lead to code that is easy to understand, to maintain, and to enhance. Furthermore, by following these coding standards our productivity as a Java developer should increase remarkably – Experience shows that by taking the time to write high-quality code right from the start we will have a much easier time modifying it during the development process. Finally, following a common set of coding standards leads to greater consistency, making teams of developers significantly more productive.

Coding standards for Java are important because they lead to greater consistency within our code and the code of our teammates. It increases code robustness. Greater consistency leads to code that is easier to understand, which in turn means it is easier to develop and to maintain. This reduces the overall cost of the applications that you create.
We have to remember that our Java code will exist for a long time, long after we have moved on to other projects. An important goal during development is to ensure that we can transition our work to another developer, or to another team of developers, so that they can continue to maintain and enhance our work without having to invest an unreasonable effort to understand our code. Code that is difficult to understand runs the risk of being scrapped and rewritten – We wouldn’t be proud of the fact that our code needed to be rewritten? If everyone is doing their own thing then it makes it very difficult to share code between developers, raising the cost of development and maintenance.
New developers, and cowboys who do not know any better, will often fight having to follow standards. They claim they can code faster if they do it their own way. They MIGHT be able to get code out the door faster, but I doubt it. Cowboy programmers get hung up during testing when several difficult-to-find bugs crop up, and when their code needs to be enhanced it often leads to a major rewrite by them because they’re the only ones who understand their code. Is this the way that we want to operate? I think I certainly do not.


No standard is perfect and no standard is applicable to all situations: sometimes we find ourselves in a situation where one or more standards do not apply. This leads me to introduce what I consider to be the prime directive of standards:

When we go against a standard, we must document it. All standards, except for this one, can be broken. If we do so, we must document why we broke the standard, the potential implications of breaking the standard, and any conditions that may/must occur before the standard can be applied to this situation.

The bottom line is that we need to understand each standard, understand when to apply them, and just as importantly when not to apply them.

Most ordinary comments within Java code explain the implementation details of that code. In contrast, the Java language specification defines a special type of comment known as a doc comment that serves to document the API of your code. A doc comment is an ordinary multiline comment that begins with /** (instead of the usual /*) and ends with */. A doc comment appears immediately before a class, interface, method, or field definition and contains documentation for that class, interface, method, or field. The documentation can include simple HTML formatting tags and other special keywords that provide additional information. Doc comments are ignored by the compiler, but they can be extracted and automatically turned into online HTML documentation by the javadoc program.
We ensure that our code should follow some basics facts about good documentations, these basics facts are –
1.      Comments should add to the clarity of the code.
2.      If the program isn’t worth documenting, it probably isn’t worth running.
3.      Take care about comments - Avoid decoration, i.e. do not use banner-like comments.
4.      Comments must be simple.
5.      Always prefer to write the documentation before you write the code.
6.      Document why something is being done, not just what.
Java programs can have two kinds of comments: implementation comments and documentation comments. Implementation comments are those found in C++, which are delimited by /*...*/, and //. Documentation comments (known as "doc comments") are Java-only, and are delimited by /**...*/. Doc comments can be extracted to HTML files using the javadoc tool.

Program can have following type of implementation comments –
1.      Block
2.      Single line
3.      Trailing
4.      End-of-line

2.2.1.1 Block Comments:-
Block comments are used to provide descriptions of files, methods, data structures and algorithms. Block comments may be used at the beginning of each file and before each method. They can also be used in other places, such as within methods. Block comments inside a function or method should be indented to the same level as the code they describe.
A block comment should be preceded by a blank line to set it apart from the rest of the code.
/*
 * Here is a block comment.
 */
Block comments can start with /*-, which is recognized by indent(1) as the beginning of a block comment that should not be reformatted. Example:
/*-
 * Here is a block comment with some very special
 * formatting that I want indent(1) to ignore.
 *
 *    one
 *        two
 *            three
 */

Note: If we don't use indent(1), we don't have to use /*- in our code or make any other concessions to the possibility that someone else might run indent(1) on our code.
Short comments can appear on a single line indented to the level of the code that follows. If a comment can't be written in a single line, it should follow the block comment format. A single-line comment should be preceded by a blank line. Here's an example of a single-line comment in Java code:
if (condition) {

    /* Handle the condition. */
    ...
}
Very short comments can appear on the same line as the code they describe, but should be shifted far enough to separate them from the statements. If more than one short comment appears in a chunk of code, they should all be indented to the same tab setting.
Here's an example of a trailing comment in Java code:
if (a == 2) {
    return TRUE;            /* special case */
} else {
    return isPrime(a);      /* works only for odd a */
}
The // comment delimiter can comment out a complete line or only a partial line. It shouldn't be used on consecutive multiple lines for text comments; however, it can be used in consecutive multiple lines for commenting out sections of code. Examples of all three styles follow:
if (foo > 1) {

    // Do a double-flip.
    ...
}
else {
    return false;          // Explain why here.
}
//if (bar > 1) {
//
//    // Do a triple-flip.
//    ...
//}
//else {
//    return false;
//}

2.2.2 Documentation Comments
Doc comments describe Java classes, interfaces, constructors, methods, and fields. Each doc comment is set inside the comment delimiters /**...*/, with one comment per class, interface, or member. This comment should appear just before the declaration:
/**
 * The Example class provides ...
 */
public class Example { ...
Notice that top-level classes and interfaces are not indented, while their members are. The first line of doc comment (/**) for classes and interfaces is not indented; subsequent doc comment lines each have 1 space of indentation (to vertically align the asterisks). Members, including constructors, have 4 spaces for the first doc comment line and 5 spaces thereafter.
If you need to give information about a class, interface, variable, or method that isn't appropriate for documentation, use an implementation block comment or single-line comment immediately after the declaration. For example, details about the implementation of a class should go in such an implementation block comment following the class statement, not in the class doc comment.
Doc comments should not be positioned inside a method or constructor definition block, because Java associates documentation comments with the first declaration after the comment.


Included in Sun’s Java Development Kit (JDK) is a program called javadoc that processes Java code files and produces external documentation, in the form of HTML files, for your Java programs. I think that javadoc is a great utility, but at the time of this writing it does have its limitations. First, it supports a limited number of tags, reserved words that mark the beginning of a documentation section. The existing tags are a very good start but I feel are not sufficient for adequately documenting your code. I’ll expand upon this statement later. For now, I present a brief overview of the current javadoc tags in the chart below, and will refer you to the JDK javadoc documentation for further details.

                     Tag
                 Used for
                Purpose

@author name
Interfaces,
Classes
Indicates the author(s) of a given piece of code. One tag per author should be used.

@deprecated
Interfaces,
Classes,
Member Functions.
Indicates that the API for class… has been deprecated and therefore should not be used any more.

@exception name description

Member Functions
Describe the exceptions that a member function throws. We should use one tag per exception and give the full class name for the exception.

@param name description

Member Functions
Used to describe a parameter passed to a member function, including its type/class and its usage. Should use one tag per parameter.

@return description

Member Functions
Describe the return value, if any, of a member function. We should indicate the type/class and the potential use(s) of the return value.

@since
Interfaces,
Classes,
Member Functions
Indicates how long the item existed, i.e. since Java Development Kit (JDK) 1.1

@see ClassName
Interfaces,
Classes,
Member Functions, Fields
Generate a Hypertext link in the documentation to the specified class. We can and probably should use a fully qualified class name.
@see ClassName#memberFunctionName
Interfaces,
Classes,
Member Functions, Fields
Generate a hypertext link in the documentation to the specified member function. We can, and should probably use a fully qualified class name. 
@version text
Interfaces,
Classes
Indicates the version information for a given piece of code.


The way that we document our code has a huge impact both on our own productivity and on the productivity of everyone else that later maintains and enhances it. By documenting our code early in the development process we become more productive because it forces we to think through our logic before we commit it to code. Furthermore, when we revisit code that we wrote days or weeks earlier we can easily determine what we were thinking when we wrote it – it is documented for we already.

I’m a firm believer in maximizing the productivity of systems professionals. Because I also recognize that an application spends the majority of its existence being maintained, not developed, I am very interested in anything that can help to make my code easier to maintain and to enhance, as well as to develop. Never forget that the code that we write today may still be in use many years from now and will likely be maintained and enhanced by somebody other than I. We must strive to make our code as “clean” and understandable as possible, because these factors make it easier to maintain and to enhance. We will understand naming convention step-by-step in following pattern (this is not mandatory for all sub-heading) …
v  Naming conventions
v  Visibility
v  Documentation conventions
v  Techniques for writing clean Java code

Member Functions should be named using a full English description, using mixed case with the first letter of any non-initial word capitalized. It is good practice to name a method according to its work. It is also common practice for the first word of a member function name to be a strong, active verb. For instance
Ø  openMail();
Ø  closeMail();
Ø  saveMail();
Ø  deleteMail();              
This convention results in member functions whose purpose can often be determined just by looking at its name. Although this convention results in a little extra typing by the developer, because it often results in longer names, this is more than made up for by the increased understandability of our code.

We will discuss accessors, member functions that get and set the values of fields (fields/properties). The naming conventions for accessors, however, are summarized below.

3.1.1.1 Getter:-
Getters are member functions that return the value of a field. We should prefix the word ‘get’ to the name of the field, unless it is a boolean field and then we prefix ‘is’ to the name of the field instead of ‘get.’ For Example –
Ø  getFirstName();
Ø  getAccountNumber();
Ø  isPersistent();

By following this naming convention we make it obvious that a member function returns a field of an object, and for boolean getters we make it obvious that it returns true or false. Another advantage of this standard is that it follows the naming conventions used by the beans development kit (BDK) for getter member functions. The main disadvantage is that ‘get’ is superfluous, requiring extra typing.

Alternative Naming Convention for Getters – Has and Can
A viable alternative, based on proper English conventions, is to use the prefix ‘has’ or ‘can’ instead of ‘is’ for boolean getters. For example, getter names such as hasDependents() and canPrint() make a lot of sense when we are reading the code. The problem with this approach is that the BDK will not pick up on this naming strategy (yet).

3.1.1.2 Setters:-
Setters, also known as mutators, are member functions that modify the values of a field. We should prefix the word ‘set’ to the name of the field, regardless of the field type. For example
Ø  setFirstName(String name);
Ø  setAccount(int accountNumber);
Ø  setPersistent(boolean persist);

Following this naming convention we make it obvious that a member function sets the value of a field of an object. Another advantage of this standard is that it follows the naming conventions used by the beans development kit (BDK) for setter member functions. The main disadvantage is that ‘set’ is superfluous, requiring extra typing.

Constructors are member functions that perform any necessary initialization when an object is first created. Constructors are always given the same name as their class. For example, a constructor for the class Customer would be Customer(). Note that the same case is used. For instance –
Ø  Customer();
Ø  Account();
This naming convention is set by Sun and must be strictly adhered to.

For a good design where we minimize the coupling between classes, the general rule of thumb is to be as restrictive as possible when setting the visibility of a member function. If member function doesn’t have to be public then make it protected, and if it doesn’t have to be protected then make it private.

      Visibility
Description
         Proper Usage
           public
A public member function can be invoked by any other member function in any other object or class.
When the member function must be accessible by objects and classes outside of the class hierarchy in which the member function is defined.


           protected
A protected member function can be invoked by any member function in the class in which it is defined or any subclasses of that class.
When the member function provides behavior that is needed internally within the class hierarchy but not externally.




           private
A private member function can only be invoked by other member functions in the class in which it is defined, but not in the subclasses.
When the member function provides behavior that is specific to the class. Private member functions are often the result of refactoring, also known as reorganizing, the behavior of other member functions within the class to encapsulate one specific behavior.





No visibility is indicated. This is called default or package visibility, and is sometimes referred to as friendly visibility. The member function is effectively public to all other classes within the same package, but private to classes external to the package.
This is an interesting feature, but be careful with its use. I use it when I’m building domain components, collections of classes that implement a cohesive business concept such as “Customer”, to restrict access to only the classes within the component/package.




Throughout this white paper I will use the term field to refer to an attribute, which the Beans Development Kit (BDK) calls a property. A field is a piece of data that describes an object or class. Fields may be a base data type like a string or a float, or may be an object such as a customer or bank account. To adhere following important lines when declaring fields –
1.      Use a full English descriptor for field names: - we should use a full English descriptor to name fields to make it obvious what the field represents. Fields that are collections, such as arrays or vector, should be given names that are plural to indicate that they represents multiple values. For example
Ø  employeeName;
Ø  employeeId;

2.      Acronym should be lower case – if the name of the field begins with an acronym, such as sqlDatabase, then the acronym should be lowercase. For example – sqlDatabase should not write this sQLDatabase.
3.      All fields name should be meaningful, and shows that what type of value it will hold.
4.      Always avoid abbreviation format for naming a field.
5.      Always avoid using java key words as field name.
6.      Naming Constant - In Java, constants, values that do not change, are typically implemented as static final fields of classes. The recognized convention is to use full English words, all in uppercase, with underscores between the words. Examples are -
Ø  MINIMUM_BALANCE
Ø  MAX_VALUE
Ø  DEFAULT_START_DATE

The main advantage of this convention is that it helps to distinguish constants from variables. We will see later in the document that we can greatly increase the flexibility and maintainability of our code by not defining constants, instead we should define getter member functions that return the value of constants.
7.      Familiar Names – we should use the words that exist in the terminology of the target domain. If our users refer to their clients as customer, then use the name “Customer” for the class not “Client”.
8.      Avoid excessively long names – name should be meaningful and descriptive but not excessively long. Max size for this should be up to 25 characters
9.      Use descriptive name and do not attempt to shorten names by removing vowels.
10.  Don’t use name that differ only in case.
11.  Naming Collection – A collection, such as an array or a vector, should be given a pluralized name representing the types of objects stored by an array. The name should be a full English descriptor with the first letter of all non-initial words capitalized. For example –
Ø  customers;
Ø  orderItems;
The main advantage of this convention is that it helps to distinguish fields that represent multiple values (collections) from those that represent single values (non-collections).

A local variable is an object or data item that is defined within the scope of a block, often a member function. The scope of a local variable is the block in which it is defined. The important coding standards for local variables focus on:
Ø  Naming conventions

In general, local variables are named following the same conventions as used for fields, in other words use full English descriptors with the first letter of any non-initial word in uppercase. For the sake of convenience, however, this naming convention is relaxed for several specific types of local variable:
Ø  Streams
Ø  Loop counters
Ø  Exceptions

When there is a single input and/or output stream being opened, used, and then closed within a member function the common convention is to use in and out for the names of these streams, respectively. For a stream used for both input and output, the implication is to use the name inOut. A common alternative to this naming convention is to use the names inputStream, outputStream, and ioStream instead of in, out, and inOut respectively. To tell you the truth I like this alternative better, but the fact remains that the names in and out are what Sun suggests, so that’s what you should probably stick with.

Because loop counters are a very common use for local variables, and because it was acceptable in C/C++, in Java programming the use of i, j, or k, is acceptable for loop counters. If we use these names for loop counters, use them consistently. A common alternative is to use names like loopCounter or simply counter, but the problem with this approach is that we often find names like counter1 and counter2 in member functions that require more than one counter. The bottom line is that i, j, k work as counters, they’re quick to type in, and they’re generally accepted.
A major disadvantage of using single letter names for counters, or for anything, is that when we try to search for its use within a code file we will obtain many false hits – consider the ease of searching for loopCounter over the letter i.

Because exception handling is also very common in Java coding the use of the letter e for a generic exception is considered acceptable.

The standards that are important for parameters/arguments to member functions focus on how they are named and how they are documented. Throughout this white paper I will use the term parameter to refer to a member function argument.
Parameters should be named following the exact same conventions as for local variables. As with local variables, name hiding is an issue (if you aren’t using accessors). Some examples are –
Ø  customer
Ø  inventoryItem
Ø  in
Ø  e

An alternative is to name parameters that align to an existing field with the same name as the existing field. For example, if Account has an attribute called balance and we needed to pass a parameter representing a new value for it the parameter would be called balance. The field would be referred to as this.balance in the code and the parameter would be referred to as balance (we could also invoke the appropriate accessor method).  The disadvantage of this approach is name hiding problem and it is easy to forget to use “this” object.  But I my view it is good approach, if developer shows own maturity.

This unit concentrates on standards and guidelines for classes, interfaces, packages, and compilation units. A class is a template from which objects are instantiated (created). Classes contain the declaration of fields and member functions. Interfaces are the definition of a common signature, including both member functions and fields, which a class that implements an interface must support. A package is a collection of related classes. Finally, a compilation unit is a source code file in which classes and interfaces are declared. Because Java allows compilation units to be stored in a database, an individual compilation unit may not directly relate to a physical source code file.

The standards that are important for classes are based on:

3.5.1.1 Naming convention: –
The standard Java convention is to use a full English descriptor starting with the first letter capitalized using mixed case for the rest of the name. It is good practice to use noun when naming a class.  Examples are –
Ø  AddressDetails;
Ø  Customer
Ø  String

3.5.1.2 Class visibility: –
Classes may have one of two visibilities: public or package (default). Public visibility is indicated with the keyword public and package visibility is not indicated (there is no keyword). Public classes are visible to all other classes whereas classes with package visibility are visible only to classes within the same package.
1. Use package visibility for classes internal to a component. With package visibility you hide classes within the package, effectively encapsulating them within our component.
2. Use public visibility for the facades of components. Components are encapsulated by façade classes, classes that implement the interface of the component and that route messages to classes internal to the component.

The following information should appear in the documentation comments immediately preceding the definition of a class:
Ø  The purpose of the class. Developers need to know the general purpose of a class so they can determine whether or not it meets their needs. I also make it a habit to document any good things to know about a class, for example is it part of a pattern or are there any interesting limitations to using it.
Ø  Known bugs8. If there are any outstanding problems with a class they should be documented so that other developers understand the weaknesses/difficulties with the class. Furthermore, the reason for not fixing the bug should also be documented. Note that if a bug is specific to a single member function then it should be directly associated with the member function instead.
Ø  The development/maintenance history of the class. It is common practice to include a history table listing dates, authors, and summaries of changes made to a class. The purpose of this is to provide maintenance programmers insight into the modifications made to a class in the past, as well as to document who has done what to a class. As with member functions, this information is better contained in a configuration management system, not the source files itself.
Ø  Document applicable invariants. An invariant is a set of assertions about an instance or class that must be true at all "stable" times, where a stable time is defined as the period before a member function is invoked on the object/class and immediately after a member function is invoked. By documenting the invariants of a class you provide valuable insight to other developers as to how a class can be used.
Ø  The concurrency strategy. Any class that implements the interface Runnable should have its concurrency strategy fully described. Concurrent programming is a complex topic that is new for many programmers; therefore you need to invest the extra time to ensure that people can understand your work. It is important to document your concurrency strategy and why you chose that strategy over others. Common concurrency strategies include the following: Synchronized objects, balking objects, guarded objects, versioned objects, concurrency policy controllers, and acceptors.

3.5.1.4 Declaration convention: –
There are two things that must be considering during the declaration of a class
1.      Apply the “final” key words sensibly.
2.      Always maintain the order among the member function and fields. The order of member of a class differs from architecture to architecture. But, according to my opinion,
Ø  Static fields (private, protected, public)
Ø  Private fields
Ø  Protected fields
Ø  Public fields
Ø  Constructor()
Ø  Finalize()
Ø  Static or instance block{}
Ø  Static function (private, protected, public)()
Ø  Private function()
Ø  Protected function()
Ø  Public function()

Note – once the sequence decided, then all members should stick on that format.

The standards that are important for interfaces are based on:

3.5.2.1 Naming Interfaces: -
The Java convention is to name interfaces using mixed case with the first letter of each word capitalized. The preferred Java convention for the name of an interface is to use a descriptive adjective, such as Runnable or Cloneable, although descriptive nouns, such as Singleton or DataInput, are also common.

The following information should appear in the documentation comments immediately preceding the definition of an interface:
1.      The purpose. Before other developers will use an interface, they need to understand the concept that it encapsulates. In other words, they need to know its purpose. A really good test of whether or not you need to define an interface is whether or not you can easily describe its purpose. If you have difficulties describing it, then chances are pretty good you do not need the interface to begin with. Because the concept of interfaces is new to Java, people are not yet experienced in their appropriate use and they are likely to overuse them because they are new. Just like the concept of inheritance, and in particular multiple inheritance, was greatly abused by developers new to object-orientation, I suspect that interfaces will also be greatly abused at first by programmers new to Java.
How it should and shouldn’t be used. Developers need to know both how an interface is to be used, as well as how it shouldn’t be used. Because the signature for member functions is defined in an interface, for each member function signature you should follow the member function documentation conventions discussed in section 3.1.1.

The standards that are important for packages are based on:

There are several rules associated with the naming of packages. In order, these rules are:
1.      Identifiers are separated by periods. To make package names more readable, Sun suggests that the identifiers in package names be separated by periods. For example, the package name java.awt is comprised of two identifiers, java and awt.

2.       The standard java distribution packages from Sun begin with the identifier ‘java’ or ‘javax’. Sun has reserved this right so that the standard java packages are named in a consistent manner regardless of the vendor of your Java development environment.

3.      Local package names begin with an identifier that is not all upper case. Local packages are ones that are used internally within your organization and that will not be distributed to other organizations. Examples of these package names include persistence.mapping.relational and interface.screen.

4.      Global package names begin with the reversed Internet domain name for your organization. A package that is to be distributed to multiple organizations should include the name of the originating organization’s domain name, with the top-level domain type in lower case. For example, to distribute the previous packages, I would name them com.greensoft.persistence.mapping.relational and com.greensoft.interface.screens. The prefix (.com) should be lower case and should be one of the standard Internet top-level domain names (currently com, edu, gov, mil, net, org).

5.      Package names should be singular. The common convention is to use singular names for package names, such as interface.screen, and not a plural, such as interface.screens.

We should maintain one or more external documents that describe the purpose of the packages developed by our organization. For each package we should document:
1.     The rationale for the package. Other developers need to know what a package is all about so that they can determine whether or not they want to use it, and if it is a shared package whether or not they want to enhance or extend it.
2.    The classes in the package. Include a list of the classes and interfaces in the package with a brief, online description of each so that other developers know what the package contains. Oracle-Sun suggests creating an HTML file called index.html for each package, putting the file into the appropriate directory for the package. A better name would be the fully qualified name of the package, postfixed with .html, so that we do not have to worry about accidentally overwriting one package documentation file with another.

The standards and guidelines for compilation units are based on:

3.5.4.1 Naming a Compilation Unit:-
A compilation unit, in this case a source code file, should be given the name of the primary class or interface that is declared within it. Use the same name for the package/class for the file name, using the same case. The extension .java should be postfixed to the file name. Examples are –
Ø  Customer.java
Ø  Singleton.java
Ø  AddressDetails.java

Although we should strive to have only one class or interface declaration per file, it sometimes makes sense to define several classes (or interfaces) in the same file. My general rule of thumb is that if the sole purpose of class B is to encapsulate functionality that is needed only by class A then it makes sense that class B appear in the same source code file as class A. As a result, I have separated the following documentation conventions that apply to a source code file, and not specifically to a class:
1.      For files with several classes, list each class. If a file contains more than one class we should provide a list of the classes and a brief description for each.
2.      [OPTIONAL] The file name and/or identifying information. The name of the file should be included at the top of it. The advantage is that if the code is printed we know what the source file for the code is. The disadvantage is that if we change the source file name we also need to update our documentation, therefore if we have a sophisticated source control system (and if we don’t then get one) we might want to not include the source file name.
3.      Copyright information. If applicable we should indicate any copyright information for the file. It is common to indicate the year of the copyright and the name of the individual/organization that holds the copyright. Note that the code author may not be the holder of the copyright.




In this section we will cover several techniques that help to separate the professional developers from the hack coders. These techniques are:
1.      Document the code.
2.      Paragraph the code.
3.      Paragraph and punctuate multiline statements.
4.      Use whitespace.
5.      Specify the order of message sends.
6.      Write short, single command lines.
7.      Organize Code Sensibly.
8.      Always place Constants on the Left Side of Comparisons.
The Sun Microsystems suggests that fields not be declared public for reasons of encapsulation, but I would go further to state that all fields should be declared private. When fields are declared protected there is the possibility of member functions in subclasses to directly access them, effectively increasing the coupling within a class hierarchy. This makes our classes more difficult to maintain and to enhance, therefore it should be avoided. Fields should never be accessed directly; instead accessor member functions (see below) should be used.

            Visibility
Description
Proper Usage

       public
A public field can be accessed by any other member function in any other object or class.

Do not make fields public.

      

       protected
A protected field can be accessed by any member function in the class in which it is declared or by any member functions defined in subclasses of that class.


Do not make fields protected.

      

       private
A private field can only be accessed by member functions in the class in which it is declared, but not in the subclasses.

All fields should be private and be accessed by getter and setter member functions (accessors).


For fields that are not persistent (they will not be saved to permanent storage) you should mark them as either static or transient. This makes them conform to the conventions of the BDK.

I’d like to share several techniques with all developers from Building Object Applications That Work that, in addition to following standards, lead to greater productivity:

1.      Program for people, not the machine. The primary goal of our development efforts should be that our code is easy for other people to understand. If no one else can figure it out, then it isn’t any good. We should always obey to naming conventions, documentation of our code, to paragraph it.

2.      Design first, then code. Have we ever been in a situation where some of the code that program relies on needs to be changed? Perhaps a new parameter needs to be passed to a member function, or perhaps a class needs to be broken up into several classes. How much extra work did we have to do to make sure that our code works with the reconfigured version of the modified code? Did we ask ourselves why somebody didn’t stop and think about it first when he or she originally wrote the code so that this didn’t need to happen? That they should have DESIGNED it first? Of course we did. If we take the time to figure out how we are going to write our code before we actually start coding we’ll probably spend less time writing it. Furthermore, we’ll potentially reduce the impact of future changes on our code simply by thinking about them up front.

3.      Develop in small steps. I have always found that developing in small steps, writing a few member functions, testing them, and then writing a few more member functions is often far more effective than writing a whole bunch of code all at once and then trying to fix it. It is much easier to test and fix ten lines of code than 100, in fact, I would safely say that you could program, test, and fix 100 lines of code in ten 10-line increments in less than half the time than you could write a single one-hundred line block of code that did the same work. The reason for this is simple. Whenever you are testing your code and you find a bug you almost always find the bug in the new code that you just wrote, assuming of course that the rest of the code was pretty solid to begin with. You can hunt down a bug a lot faster in a small section of code than in a big one. By developing in small incremental steps you reduce the average time that it takes to find a bug, which in turn reduces your overall development time.

4.      Read, read, read. This industry moves far too quickly for anyone to sit on their laurels. In fact, friends of mine within Sun estimate that it’s a full time job for two to three people just to keep up with what’s happening with Java, let alone what’s happening in the object-orientation field or even development in general. That says to me that you need to invest at least some time trying to keep up. To make things easier for you, I’ve created an online reading list indicating what I consider to be the key development books that you should consider reading.

5.      Work closely with your users. Good developers work closely with their users. Users know the business. Users are the reason why developers create systems, to support the work of users. Users pay the bills, including the salaries of developers. You simply can’t develop a successful system if you do not understand the needs of your users, and the only way that you can understand their needs is if you work closely with them.
6.      Keep your code simple. Complex code might be intellectually satisfying to write but if other people can’t understand it then it isn’t any good. The first time that someone, perhaps even you, is asked to modify a piece of complex code to either fix a bug or to enhance it chances are pretty good that the code will get rewritten. In fact, you’ve probably even had to rewrite somebody else’s code because it was too hard to understand. What did you think of the original developer when you rewrote their code, did you think that person was a genius or a jerk? Writing code that needs to be rewritten later is nothing to be proud of, so follow the KISS rule: Keep it simple, stupid.

7.       Learn common patterns, antipatterns, and idioms. There is a wealth of analysis, design, and process patterns and antipatterns, as well as programming idioms, available to guide you in increasing your development productivity. My experience is that patterns provide the opportunity for very high levels of reuse within your software development projects.

2 comments: