Expresses all the design ideas that are in the system / Reveals intention • Contains no duplication • Minimises the number of entities such as classes, methods, functions, and the like / Fewest elements (Remove anything that doesn’t follow fi rst 3) http://martinfowler.com/bliki/BeckDesignRules.html
public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : theList) if (x[0] == 4) list1.add(x); return list1; ‚Àè } • After changing names and magic numbers // GOOD public List<Cell> getFlaggedCells() { List<Cell> fl aggedCells = new ArrayList<Cell>(); for (Cell cell : gameBoard) if (cell.isFlagged()) fl aggedCells.add(cell); return fl aggedCells; }
can’t discuss it class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private fi nal String pszqint = "102"; /* ... */ } ; • better this way class Customer { private Date generationTimestamp; private Date modi fi cationTimestamp;; private fi nal String recordId = "102"; /* ... */ };
more searchable than 7 • Avoid encoding • AccountImpl • IShapeFactory • Do not add unnecessary pre fi xes, like pre fi xing name of the project before every class
5 lines are good. • More than 10 lines is big. • Smaller functions are easy to understand. • Large functions are less reusable. • Large functions may include functionality that belong in different classes. • Large functions may hide the classes. • Smaller well named functions in well named classes will make it easier to navigate the code
code block, extract it into a method with name same as the comment. • Minimise number of local variables. • Minimise indentations in a method. • Do one thing.
function should be at one level of abstraction void compute() { input(); fl ags|= 0x0080; output(); } • If the statements are not at one level of abstraction extract them in functions with meaningful names. • Functions having one abstraction level are likely to do one thing.
Usually less than 3 variables. Circle makeCircle(double x, double y, double radius); Circle makeCircle(Point center, double radius) ; • Avoid boolean parameters. doMakeResponse(context, request, true ) • Avoid passing in nulls or returning nulls. • Use objects or maps when you need many arguments.
possibility of more cases. • When switch is used for creation of Polymorphic objects. Like in a Factory. • When switch cases are managed locally and can not scatter throughout the system.
variables. • More variables a method manipulates the more cohesive that method is to its class. • The more cohesive the methods are the more cohesive the class will be. • We want the classes to have high cohesion. • When classes lose cohesion, split them!
see if the employee is eligible for full bene fi ts if ((employee. fl ags & HOURLY_FLAG) && (employee.age > 65)) // or this? if (employee.isEligibleForFullBene fi ts())
comments e.g. warning comments // format matched kk:mm:ss EEE, MMM dd, yyyy Pattern timeMatcher = Pattern.compile ( "\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d* ” ) ; • TODO comments • Javadocs in Public API • For ampli fi cation
throws Exception { … //This is our best attempt to get a race condition //by creating large number of threads. for (int i = 0; i < 25000; i++) { WidgetBuilderThread widgetBuilderThread = new WidgetBuilderThread(widgetBuilder, parent); Thread thread = new Thread(widgetBuilderThread); thread.start(); } … } •
{ String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE; FileInputStream propertiesStream = new FileInputStream(propertiesPath); loadedProperties.load(propertiesStream); } catch(IOException e) { // No properties fi les means all defaults are loaded } } •
• Use unchecked exceptions • Provide context with exceptions. • Don’t return null • Don’t pass null Clean code is readable, but it must also be robust.
into many smaller auxiliary methods • Large class • solution - Apply single responsibility principle • Duplicate code • Too many parameters • Comments • …
Independent • should not depend on each other • Repeatable • ability to run tests in any environment • Self-validating • should have boolean output, either pass or fail • No need to manually check the logs • Timely • Unit tests should be written just before the production code that makes them pass