Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 17 Next »

 

I highly encourage you to write down here all our coding conventions. From now on nobody will be able to say "how could I know?".

Most of them are highly debatable so feel free to discuss them or even prove them wrong.

Also, the thing is that you have to know the rules to be able to break them. Proper order of coding something should look like this:

  1. You consider doing it according to this conventions, assuming you fully understand them.
  2. If your common sense tells you it's not right, it probably isn't - do it your way.
  3. But don't leave it like that, talk about it, or even better update this page.

Mes specific conventions

Model fields literals

Every time we add a new model field we should add it to the constants/PluginNameFields.java like this:

public class PluginNameFields {
 
  public final static String ORDER = "order";
}  

So we won't repeat those string literals over and over when accessing entities fields. We're gonna use:

entity.getBelongsToField(PluginNameFields.ORDER);

or even better:

import static com.qcadoo.mes.pluginName.constants.PluginNameFields;
 
entity.getBelongstoField(ORDER);

I know it's something new, and refactoring the whole system will be a horror. Let's just use it from now on, ok?

 

Java enums

For every enum field of a model we create, we should create corresponding Java enum in constants package.

For ex.

BatchNumberUniquness.java
public enum BatchNumberUniqueness {
 
  GLOBALLY("01globally"), MANUFACTURER("02manufacturer");

  private final String stringValue;
 
  private BatchNumberUniqueness(final String stringValue) {
    this.stringValue = stringValue;
  }
  
  public String getStringValue() {
    return stringValue;
  }

  public static final BatchNumberUniqueness parseString(final String string) {
    if ("01globally".equals(string)) {
      return GLOBALLY;
    } else if ("02manufacturer".equals(string)) {
      return MANUFACTURER;
    } else {
      throw new IllegalArgumentException("Couldn't parse BatchNumberUniqueness from string '" + string + "'");
    }
  }

  @Override
  public String toString() {
    return stringValue;
  }

}

 

Naming conventions

Naming literals:

EDIT: look at the mes specific convention about model field literals.

If the same string literal occurs more than once we extract it to a field like this:

private static final String L_STRING_LITERAL = "stringLiteral"

I know it was STRING_LITERAL_L before, but that convention didn't work for magic numbers, also if you think about it, that L_ upfront tells you clearly what you deal with. That it's not a plugin specific constant nor enum.

Same thing holds for magic numbers:

private static final int L_15 = 15;

 

Naming classes/packages:

If plugin name is "mes-plugins-awesome-plugin" the basic package is: com.qcadoo.mes.awesomePlugin, we can create some additional packages (and it's very rare when we should create anything else):

  • constants - we hold here classes like AwesomePluginConstants.java and maybe some model enums that are plugin specific.
  • hooks - model and view hooks like: ViewNameHooks.java, ModelNameHooks.java. If the hook class is meant to extend (on a business level) an other plugin it should have plugin abbreviation for ex. ModelNameHooksAP.java
  • validators - model validators like: ModelNameValidators.java, SomeOtherModelNameValidators.java or ModelNameValidatorsAP.java (like with the hooks)
  • listeners - view listeners like: ViewNameListeners.java, ViewNameListenersAP.java (like with the hooks)
  • states - if there is some logic regarding model states (I consider enum state model field as something that common to write it here), for ex. ModelNameStatesService.java
  • workPlansColumnExtensionhttp://wiki.qcadoo.org/display/QCDMESDOC/WorkPlans+column+extension

We add PluginName prefix only to classes that are meant to be used outside this plugin - things like: AwesomePluginConstants.java, AwesomePluginService.java.

Coding style conventions

Single line for or if statements:

Even if they are single commands, that you are sure won't grow bigger, we enclose it in { } brackets - always.

BAD

if (condition)
  doSomething(); 

GOOD

if (condition) {
  doSomething();
}  

 

We initiate objects, especially Lists (local - non field) upon creation:

Because if we won't we are in risk to letting them remain null.

BAD

String name;

if (condition) {
  name = "Michael";
}  
List<Entity> customers;

if (condition) {
   customers = loadCustomers();
}    

 

GOOD

String name = "Name not available";

if (condition) {
  name = "Michael";
}    
List<Entity> customers = new LinkedList<Entity>();

if (condition) {
  customers = loadCustomers();
}    

 

If we are dealing with 2 state enum kind of option we don't make the other option fall into simple else block.

Because number of states can change over time. The code where all different states fall into else block won't tell you anything, will just remain broken, silently.

This also applies to any options, not just model enums.

BAD

// state is either 01draft or 02accepted
 
if ("01draft".equals(state)) {
  doSomething();
} else {
  doSomethingDifferent();
}   

 

GOOD

// state is either 01draft or 02accepted

if ("01draft".equals(state)) {
  doSomething();
} else if ("02accepted".equals(state)) {
  doSomethingDifferent();
} else {
  throw new IllegalStateException("state is neither 01draft nor 02accepted");
}   
      


  • No labels