Created
May 31, 2011 12:37
-
-
Save bivas/1000436 to your computer and use it in GitHub Desktop.
Java Coding Standards
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
= 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