Skip to content

Instantly share code, notes, and snippets.

@bivas
Created May 31, 2011 12:37
Show Gist options
  • Save bivas/1000436 to your computer and use it in GitHub Desktop.
Save bivas/1000436 to your computer and use it in GitHub Desktop.
Java Coding Standards
= Motivation =
Code conventions are important to programmers for a number of reasons
- 80% of the lifetime cost of a piece of software goes to maintenance.
- Hardly any software is maintained for its whole life by the original author.
- Code conventions improve the software readability, allowing programmers to understand new code more quickly and thoroughly.
= Coding Standards =
- Naming and packaging
-- Abstract, interfaces, impls and technology impls (e.g. AbstractHibernateDAO)
-- Using [http://www.oracle.com/technetwork/java/codeconvtoc-136057.html Java standard] for method/class/member names
--- Members names should not begin with *m_* or like
--- Use CamelCase for names (methods/members: *doFoo*; classes: *DoFoo*)
--- Don't use short names to describe objects (*Component*, not *Comp*; *Application*, not *App*; *Context*, not *ctx*, etc.)
-- http://geosoft.no/development/javastyle.html
- Always use blocks in if/while/for/do statements
- Refer to objects by their interface
-- Favor interface as field type
-- Favor interface as parameter type
- Prefer primitive types over boxed primitives
- Refrain from using *Boolean* as method parameter
- Refrain from using *String* as method parameter (Where *enum* or *Object* are suitable)
-- Define types that best describe the behavior (might hold String as fields)
- Avoid long parameter list for methods and/or constructors. No more than 4 params.
- Objects (including boxed primitives) should be tested for equality using the equals() method, only primitives can be tested for equality using the identity operator (‘==’)
- Don’t <nowiki>(!)</nowiki> concatenate *String*s in loops – use *StringBuilder*
-- Don't use *+* more than once in *String* concatenation
-- Prefer the use of *StringBuilder* over *String.format*
- Don't use identity operator (*==*) to check *Object* equality - use *equals()*
- Don't use *String*s or *int*s as constants - use *enum*
-- public static final String HOST_NAME = "localhost"; // OK
-- public static final int COLOR_ORANGE = 1; // Wrong
- The use of *@SuppressWarnings* should be limited to the smallest scope possible.
-- Don’t suppress warnings on class scope
-- Always document why you believe the suppression is legit
- Never throw/catch *Throwable*, use the best exception which describes the scenario
-- *Throwable* hides JVM non-recoverable errors (e.g. *OutOfMemoryError*)
-- Catching *Error* is plausible in end points (integration between frameworks)
- Don't use *System.out.println()* or *System.err.println()* for info or error reporting - use *org.apache.commons.logging.Log*
-- Log instances should be *private static final*
- Refrain from promoting bug-prone code
-- Eclipse warning should be handle (dead code, unused members/methods etc)
-- High priority findBugs and PMD errors
= Best Practices =
- Keep it simple!
- Keep class/method visibility as low as possible (impls should be package visible)
- Hide the implementation as best as possible (packages should communicate via interfaces)
- Prefer collections over arrays
-- Never return *null* but empty collection. e.g. *Collections.emptyList()*
-- Don't create empty collection just for *return* purposes, use *Collection.emptyList()*
- Prefer stateless objects
- Minimize mutability
-- Consider using *final* fields
-- Consider using *final* parameter in methods
-- Consider using the builder pattern
- Consider the builder pattern when faced with too much constructor options
- Consider the strategy pattern when faces with too many methods of identical operation (or to avoid *instance of*)
- Use 3rd party libraries where possible – don’t re-invent the wheel
- Additional reading
-- http://www.squarebox.co.uk/download/javatips.html
-- http://www.perlmonks.org/?node_id=744932
-- http://confluence.sakaiproject.org/display/SAKDEV/Best+Practices+for+High+Quality+Code- BestPracticesforHighQualityCode-KeepItSimpleStupid
-- http://java.sun.com/docs/books/effective/toc.html
= JavaDoc =
- JavaDoc classes based on a shared template
- Document when you complete development and not before
-- This will make the documentation up to date with the code.
- Classes and Interfaces should be documented, the guideline is who will use it
-- The more will use it the more it should be self explain. For example a API with thirdParty should be well documented while inner class can have a single line of document
-- Don't over document!
- Use task oriented JavaDoc comments (TODO, FIXME, XXX)
-- *TODO* - used to indicate partial code that needs finish
-- *FIXME* - bogus code, might be broken
-- *XXX* - bogus code, working but should be refactored
- Add identification to task comments. e.g. TODO [someuser] update to final version
= Unit/Integration Test =
- In general if your code contain logic it can and should be tested (e.g. domain object has no logic)
- Unit test should be unit and not integration, prefer mocking of callable objects
-- Integration tests should be identified by *IntegrationTest* suffix
- Unit test must include assertion (output and/or logic)
- Each unit test should include a single case (no multiple assertions)
- Strive for *100%* code coverage when unit testing your classes
- DAO tests should be transactional to prevent garbage in DB
= Spring Framework =
- Prefer constructor injection
-- Refrain from injecting directly to object's field
- Prefer AOP over wrappers or empty super types where possible
- Prefer singleton scope for beans
- Prefer the use of object factories for prototype objects, this way it's easy to inject additional dependancies
- Use configuration properties for configurable values (e.g. ${database.connection.max} )
= Persistency (Hibernate) =
- Prefer JPA over Hibernate annotation over annotation mapping
-- HQL/SQL queries should be declared at the type level and not stored as strings
-- Objects shouldn't be familiar with their persistence mechanism
- Domain object should be POJOs, setters methods and empty constructor should be private-package (default) visible
- Don't include logic (like validation) in domain object, use *Hibernate Validator* or other validator pattern
- Always implement *hashCode()* and *equals()*
-- Use *HashCodeBuilder* and *EqualsBuilder* (from Apache Commons) - don't use reflection building
- For debug, implement *toString()*
-- Use *ToStringBuilder* (from Apache Commons) - don't use reflection building
= Serialization =
== Protocol Buffers ==
- Prefer the use of objects over *String*s
- Set default value if applicable
- If a message can't exist on its own - place it as an internal message in the main message
- Field name should be camel-case but separated with underscores (_)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment