Documents
Software
API
FAQ
Success Stories
Internal
Site
Contact
Home
| |
NaradaBrokering Project:
Developer Information |
|
|
This document cover 5 related aspects of efforts within the NaradaBrokering
project. The issues specifically addressed here pertain to
Here we try to leverage, and learn from, experiences in other large successful
projects such as the projects under the aegis of the Apache Software Foundation and
Globus.
NaradaBrokering Coding
conventions:
To
improve readability of code that is part of the NaradaBrokering project
developers are strongly urged to conform to
Sun's Java
coding conventions. In addition to this the following conventions are also
in place.
-
Package import statements must be for
individual classes i.e. import java.util.* is not allowed.
-
Variable names should reflect the
use/purpose of that variable. No abbreviations or single letter variable
names are allowed.
-
Curly brackets are NOT allowed on
separate lines.
-
Single line conditional statements should
be inside brackets. For e.g.
if (toAdd) {
value = value + valueToAdd;
}
-
No two classes within the distribution
are allowed to have the same name. That is, <package1>.ClassA and<package2>.classB
are not allowed.
-
Classes released as part of the
NaradaBrokering's source distribution must have their package names
start with cgl.narada.
-
Except for the main() method System.exit()
should not be used anywhere else in the code.
Also, here are few other recommendations from the great Bruce Eckel. These are
reproduced in verbatim here from his book Thinking in Java.
- Capitalize the first letter of class
names. The first letter of fields, methods, and objects (handles) should be
lowercase. All identifiers should run their words together, and capitalize
the first letter of all intermediate words. For example:
ThisIsAClassName
thisIsAMethodOrFieldName
Capitalize all the letters of static final primitive identifiers that have
constant initializers in their definitions. This indicates they are
compile-time constants.
- When creating a class for
general-purpose use, follow a “canonical form” and include definitions for
equals( ), hashCode( ), toString( ), clone( )
(implement Cloneable), and implement Serializable.
- Methods should be kept to brief,
functional units that describe and implement a discrete part of a class
interface. Ideally, methods should be concise; if they are long you might
want to search for a way to break them up into several shorter methods. This
will also foster reuse within your class. (Sometimes methods must be large,
but they should still do just one thing.).
- Try to keep classes small and
focused.
- Keep things as “private as
possible.” Once you publicize an aspect of your library (a method, a class,
a field), you can never take it out. If you do, you’ll wreck somebody’s
existing code, forcing them to rewrite and redesign. If you publicize only
what you must, you can change everything else with impunity, and since
designs tend to evolve this is an important freedom. Privacy is especially
important when dealing with multithreading – only private fields can
be protected against un-synchronized use.
- Watch out for “giant object
syndrome.” This is often an affliction of procedural
programmers who are new to OOP and who end up writing a procedural program
and
sticking it inside one or two giant objects. With the exception of
application frameworks,
objects represent concepts in your application, not the application.
- If you must do something ugly, at
least localize the ugliness inside a class.
- Avoid using “magic numbers,” which
are numbers hard-wired into code. These are a nightmare if you need to
change them, since you never know if “100” means “the array size” or
“something else entirely.” Instead, create a constant with a descriptive
name and use the constant identifier throughout your program. This makes the
program easier to understand and much easier to maintain.
- 1In terms of constructors and
exceptions, you’ll generally want to re-throw any exceptions that you catch
while in a constructor if it causes failure of the creation of that object,
so the caller doesn’t continue blindly, thinking that the object was created
correctly.
- If your class requires any cleanup
when the client programmer is finished with the object, place the cleanup
code in a single, well- defined method with a name like cleanup( )
that clearly suggests its purpose. In addition, place a boolean flag in the
class to indicate whether the object has been cleaned up. In the finalize( )
method for the class, check to make sure that the object has been cleaned up
and throw a class derived from RuntimeException if it hasn’t, to indicate a
programming error. Before relying on such a scheme, ensure that finalize( )
works on your system. (You might need to call
System.runFinalizersOnExit(true) to ensure this behavior.)
- Choose interfaces over
abstract classes. If you know something is going to be a base class,
your first choice should be to make it an interface, and only if you’re
forced to have method definitions or member variables should you change it
to an abstract class. An interface talks about what the client wants to do,
while a class tends to focus on (or allow) implementation details.
- Use design patterns to eliminate
“naked functionality.” That is, if only one object of your class should be
created, don’t bolt ahead to the application and write a comment “Make only
one of these.” Wrap it in a singleton. If you have a lot of messy code in
your main program that creates your objects, look for a creational pattern
like a factory method in which you can encapsulate that creation.
Eliminating “naked functionality” will not only make your code much easier
to understand and maintain, it will also make it more bulletproof against
the well-intentioned maintainers that come after you.
NaradaBrokering
Testing:
Every class must have a JUnit test
case associated with it. The test classes should reside in the /test directory
under each package. This in tandem with ANT should allow us to run automated
test cases to see the effect of any changes that developers might have made to
the codebase. In general developers are first expected to resolve conflicts (if
any) in their local spaces and then proceed to run these automated test cases.
Finally, the automated test cases need to be run after a commit too.
NaradaBrokering
Logging:
Logging must use the cgl.narada.logging library for logging purposes. This
allows users to switch between JDK's logging and Log4j.
NaradaBrokering Bug
Reports:
Bug reporting should be done using BugZilla. This is currently available at
http://gf8.ucs.indiana.edu/bugzilla/enter_bug.cgi?product=NaradaBrokering
NaradaBrokering
Version Control:
We
use CVS for version control. If you are not familiar with this piece of
software, please read some background material on this first. CVS comes with an
excellent reference manual and this The latest CVS client can be downloaded from
http://www.cvshome.org. The NaradaBrokering repository is available at
gf5.ucs.indiana.edu. This repository is currently available only to developers
contributing to the project.
Users only have to define two environment variables on their remote clients
systems to have full access to CVS:
export CVSROOT=:ext:yourlogin@server.host:/full/path/to/the/repository
export CVS_RSH=`which ssh` # or full path to local ssh binary
Of
course for NT-based users, you need to use the corresponding set statements.
Here is the command for users to checkout the software.
D:\NB>cvs -d :ext:bob@gf5.ucs.indiana.edu:/home/nb/cvsroot
checkout -kb NaradaBrokering
|