Last modified 16 years ago
Last modified on 09/11/09 14:56:36
Here we will be adding examples of good code, if you want to add somethings, please talk with the integrators first.
- Example for good equals method.
- You can use the mouse-right-button menu in the source code area of eclipse -> Source -> "Generate hashCode() and equals()..." for template, but refactor it to look like the example bellow:
@Override public boolean equals(Object object) { if (object == null) { return false; } if (object == this) { return true; } if (object.getClass() != this.getClass()) { return false; } // Custom code here... }
- You can use the mouse-right-button menu in the source code area of eclipse -> Source -> "Generate hashCode() and equals()..." for template, but refactor it to look like the example bellow:
- Writing if, else, else if, for, while, do while, try, catch, finally statements, blocks.
- First of all always put curly brackets after the special word that opens the statement, even if the statement contains one row.
if (some_condition) { System.out.println("pass"); }
- Insert spaces between the brackets and the words. The opening bracket of a statement is on the row where the statement is!
while (some_condition) { // something... }
- When writing conditions put spaces between the operands and the operators!
if (a != b) { System.out.println("a is not the same as b"); }
- if-else if- else example:
if (a != b) { // something... } else if (c != d) { // other thing... } else if ((b == c) && (a == d)) { // third thing, I put the brackets for easier reading, they are not mandatory. } else { // four... }
- for examples
for (i = 0; i < n; i++) { // do something... }
for (Some_iterable_type some_var : some_iterable) { // do something... }
- try-catch-finally... The same as the above as spacing and etc...
try { // some code } catch (Exception e) { // handle exception } finally { // some stuff }
- First of all always put curly brackets after the special word that opens the statement, even if the statement contains one row.
- Don't use @SuppressWarnings("all") and @SuppressWarnings("static-access") at all, other like @SuppressWarnings("synthetic-access"), @SuppressWarnings("unchecked"), etc.. you can use, but rarely only when needed!
- We don't have special conventions for naming but don't use long name or stupid ones like "stuff".
- Don't leave commented code where you tried something to be reviewed, we will be not very happy.
- Avoid writing expressions on several lines, instead use variables... but if it's needed for example in statements here are some examples :
- Write && and || to be first on the new line.
a == b && c == d || b != g && !flag
- If you Ctrl+Shift+F, please refactor your code not to have something like:
res .setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
to something likeres.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE);
but again it is advisable to use variables, something like:int closeOperation = WindowConstants.DO_NOTHING_ON_CLOSE; res.setDefaultCloseOperation(closeOperation);
- Write && and || to be first on the new line.
- Writing tests:
- Write tests that test something you wrote, not the JDK
- The tests are code, so all the above rules apply to them.
- You can use the template for tests in Eclipse, write the word test -> ctrl+space -> choose the "test - test method" template from the auto-complete menu.
- Our tests extend either UnitTestBase, either IntegrationTestBase.
- Put @After, @Before and @Test annotations.
- The first thing in a setUp method is calling the super.setUp() method, the last thing in a tearDown method is calling the super.tearDown() method.
- When caching an Exception in a test, use the logger.error(e.getMessage(), e); to see the message and than call fail(some_message_here)!
- Example for good test:
package org.sophie2.base.commons.util.position; import junit.framework.AssertionFailedError; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.sophie2.core.testing.UnitTestBase; /** * Unit test for {@link ImmVector}. * * @author Pap */ public class ImmVectorTest extends UnitTestBase { @Override @Before protected void setUp() throws Exception { super.setUp(); } @Override @After protected void tearDown() throws Exception { super.tearDown(); } /** * Tests getters of {@link ImmVector}. */ @Test public void testGetters() { float x = 5.0f; float y = 10.0f; float t = 2.0f; ImmVector v = new ImmVector(x, y, t); assertEquals(x, v.getX()); assertEquals(y, v.getY()); assertEquals(t, v.getT()); assertEquals(x / t, v.getPointX()); assertEquals(y / t, v.getPointY()); } /** * Tests {@link ImmVector#add(ImmVector)}. */ @Test public void testAdd() { ImmVector vec1 = new ImmVector(10.0f, 10.0f); ImmVector vec2 = new ImmVector(5.0f, 20.0f); ImmVector expected = new ImmVector(15.0f, 30.0f); assertEquals(expected, vec1.add(vec2)); } /** * Tests {@link ImmVector#dotProduct(ImmVector)}. */ @Test public void testDotProduct() { ImmVector vec1 = new ImmVector(1.0f, 1.0f, 0); ImmVector vec2 = new ImmVector(-1.0f, 1.0f, 0); float res = vec1.dotProduct(vec2); float expected = 0f; assertEquals(expected, res); } /** * Tests whether {@link ImmRect} is immutable. */ @Test public void testImmutable() { ImmVector v1 = new ImmVector(10.0f, 5.0f, 2.0f); ImmVector v2 = v1; assertSame(v1, v2); ImmVector result = v1.add(new ImmVector(0, 0, 1)); assertNotSame(v1, result); assertTrue(v1.equalsHomogeneously(result)); assertSame(v1, v1); } /** * Tests {@link ImmVector#equalsHomogeneously}. */ @Test public void testEqualsHomogeneouslyVectors() { ImmVector v1 = new ImmVector(10, 10, 0); ImmVector v2 = new ImmVector(20, 20, 0); assertTrue(v1.equalsHomogeneously(v2)); ImmVector v3 = new ImmVector(10, 15, 0); assertFalse(v1.equalsHomogeneously(v3)); ImmVector v4 = new ImmVector(10, 10, 1); ImmVector v5 = new ImmVector(20, 20, 2); assertTrue(v4.equalsHomogeneously(v5)); ImmVector v6 = new ImmVector(10, 10, 2); assertFalse(v6.equalsHomogeneously(v4)); } /** * Tests {@link ImmVector#opposite()}. */ @Test public void testOpposite() { ImmVector vec = new ImmVector(10.0f, 10.0f); ImmVector res = vec.opposite(); ImmVector expected = new ImmVector(-10.0f, -10.0f); assertEquals(expected, res); } /** * Tests that multiplication between a {@link ImmVector} and a * {@link ImmPoint} is undefined. */ @Test public void testDotProductVectorPoint() { ImmVector point = new ImmVector(1.0f, 1.0f, 1.0f); ImmVector vector = new ImmVector(1, 1, 0); try { point.dotProduct(vector); fail(); } catch (Throwable t) { if (t instanceof AssertionFailedError) { fail(); } } } /** * Tests that a vector must not have all zero coordinates. */ @Test public void testEqualsPointVector() { ImmVector point = new ImmVector(1, 1, 1); ImmVector vector = new ImmVector(1, 1, 0); assertFalse(point.equals(vector)); } /** * Tests that a {@link ImmVector} cannot have all coordinates equal to zero. */ @Test public void testAllZeroes() { try { new ImmVector(0, 0, 0); fail(); } catch (Throwable t) { if (t instanceof AssertionFailedError) { fail(); } } } }
- About the javadoc:
- Write good javadoc that describes classes, methods and variables
- Add yourself to the author list when you modify the logic, if your changes do not alter the logic don't do it.
- Write parameter descriptions on the next row.
- Use @see for methods or classes that are connected to your code.
- Use @since for comments of special changes since some date and write your identificator and the date.
- Use TODO, XXX and FIXME.
- Write all the @parameter, @return, descriptions as a sentences which begin with upper case letter and end with a punctuation mark. Write the description itself of the javadoc even for getters and setters, write it as sentences!
- Examples:
- Method:
/* * Moves the head position to a specified time in the timeline. If it * exceeds the length of the timeline, the position is not changed. * * @param time * The time to jump to (in seconds). * @return * The new head position. */
- Class:
/** * A class representing a given aspect of a given {@link BasePro}. * Currently used only with {@link BaseProList}s. * * {@link Aspect}s can be used by {@link BasePro}s internally to reduce the attached listeners * and the registered reads. * * This way: * 1) Some reads could be registered not with the {@link BasePro} itself but with an {@link Aspect} * of the {@link BasePro}, and so potentially lots of listeners will be attached to the * {@link Aspect}s, instead of the {@link BasePro}. * 2) ProChanges will be fired from the {@link Aspect}s of the {@link BasePro} to registered * listeners, instead of always firing from the {@link BasePro} itself. * * @author gogov */
- Class:
/** * Base class for persist formats (like ones for saving/loading books). * * Can load/save between two formats. It may support only saving or only * loading. * * @param <S> * The source type (what can be loaded). * @param <T> * The target type (what designates the target). * * @author milo */
- Method:
- Comments:
- Comment all the hard to understand algorithmic structure you write.
- Delete all the auto-generated Eclipse TODO comments.
- Comparing objects:
- Don't use '==' when comparing equal immutables that are not the same in the memory.
- Compare with 'equals' objects in way where the object, calling the 'equals' method is known : For example CONST.equals(someVar);