The goal of typed languages is to pull issues from run time to compile time.
Rules
Use types
Do not use String for non-textual values
Do not use Strings for dates - it is always formatted!
Avoid using boolean parameters - hard to read, "magic numbers"
Create exception types instead of error codes
Enums
Enums are static constants
You can static import enums to shorten the code
Enums are created threadsafe
Always use enums for a finit set of constants
Use enum to map information
Prefer enums to maps
Prefer enums to switches
Enums cannot have a parent class but can implement interfaces
Example: Bad: Implementation with collections and procedures
public final class ContractFormatter implements Serializable {
// They belong to formatFareFamily(), low cohesion
// Misplaced constants
// Duplications: they are defined sever times again and again...
private static final String FORMATTED_FIRST_CLASS_FAM = "First";
private static final String FORMATTED_BUSINESS_FAM = "Business";
private static final String FORMATTED_ECONOMY_FAM = "Economy";
private static final String FIRST_FAM = "FIRST";
private static final String BUSINESS_FAM = "BUSINESS";
private static final String ECONOMY_FAM = "ECONOMY";
private static final String FORMATTED_ECONOMY_SAVER_FAM = "Economy Saver";
private static final String ECOSAVER_FAM = "ECOSAVER";
private static final String LIGHT_FB = "LIGHT_BUNDLE";
private static final String CLASSIC_FB = "CLASSIC_BUNDLE";
private static final String BUSINESS_FB = "BUSINESS_BUNDLE"; //FB_TODO: chage to final name
private static final String FORMATTED_LIGHT_FB = "Light";
private static final String FORMATTED_CLASSIC_FB = "Classic";
private static final String FORMATTED_BUSINESS_FB = "Business"; //FB_TODO: chage to final name
// Simple property implemented as a collection
// It belongs to isFareBundle(), low cohesion
private static final Set<String> fareBundleStrings = ImmutableSet.of(LIGHT_FB, CLASSIC_FB, BUSINESS_FB);
public boolean isFareBundle(String famOrBundle) {
return fareBundleStrings.contains(famOrBundle);
}
// Simple mapping implemented as a procedure
public String formatFareFamily(String famOrBundle) {
String fareFamily = famOrBundle;
switch (famOrBundle) {
case ECOSAVER_FAM:
fareFamily = FORMATTED_ECONOMY_SAVER_FAM;
break;
case ECONOMY_FAM:
fareFamily = FORMATTED_ECONOMY_FAM;
break;
case BUSINESS_FAM:
fareFamily = FORMATTED_BUSINESS_FAM;
break;
case FIRST_FAM:
fareFamily = FORMATTED_FIRST_CLASS_FAM;
break;
case LIGHT_FB:
fareFamily = FORMATTED_LIGHT_FB;
break;
case CLASSIC_FB:
fareFamily = FORMATTED_CLASSIC_FB;
break;
case BUSINESS_FB:
fareFamily = FORMATTED_BUSINESS_FB;
break;
default:
break;
}
return fareFamily;
}
}