Slide 1

Slide 1 text

Clean Code Anil Wadghule

Slide 2

Slide 2 text

– Martin Fowler “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Kent Beck’s Design Rules • Runs all the tests • 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

Slide 5

Slide 5 text

Software Entropy • The Broken Window • Don’t leave code with broken windows.

Slide 6

Slide 6 text

Clean Code: A Handbook of Agile Software Craftsmanshi p by Robert C. Martin

Slide 7

Slide 7 text

Naming

Slide 8

Slide 8 text

Names • Use intention revealing names 
 int d; // elapsed time in day s • Instead use 
 int elapsedTimeInDays;

Slide 9

Slide 9 text

Use Intention revealing names • See this 
 // BAD public List getThem() { List list1 = new ArrayList(); for (int[] x : theList) if (x[0] == 4) list1.add(x); return list1; ‚Àè } • After changing names and magic numbers 
 // GOOD public List getFlaggedCells() { List fl aggedCells = new ArrayList(); for (Cell cell : gameBoard) if (cell.isFlagged()) fl aggedCells.add(cell); return fl aggedCells; }

Slide 10

Slide 10 text

Use pronounceable names • If you can’t pronounce it, you 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"; /* ... */ };


Slide 11

Slide 11 text

Use searchable names • Make this searchable • MAX_CLASSES_PER_STUDENT is 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

Slide 12

Slide 12 text

Naming consistency • Classes and objects should be nouns • Manager, Generator, Processor • Method names should start with verbs • isValid(), getUsername();

Slide 13

Slide 13 text

Naming consistency • Pick one word per concept (No synonyms) • Don’t mix concepts • Don’t be cute • Don’t pun • Use Solution Domain Names (Programmer friendly) • Use Problem Domain Names (Domain friendly)

Slide 14

Slide 14 text

Scope Rule • Smaller the scope of the variable smaller the name • Larger the scope of the variable larger the name.

Slide 15

Slide 15 text

Functions

Slide 16

Slide 16 text

Small functions • Functions should be small • 4 to 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

Slide 17

Slide 17 text

Small functions • Instead of adding a comment on a 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.

Slide 18

Slide 18 text

Same level of abstraction • All the statements in a 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.

Slide 19

Slide 19 text

Command Query Separation • Function should either do something or answer something, doing both is confusing

Slide 20

Slide 20 text

Function arguments • Keep the function arguments to the minimum. 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.

Slide 21

Slide 21 text

Argument objects Circle makeCircle(double x, double y, double radius) ; Circle makeCircle(Point center, double radius);

Slide 22

Slide 22 text

The Stepdown Rule • Reading code from Top to Bottom • Follow Stepdown rule

Slide 23

Slide 23 text

Switch cases

Slide 24

Slide 24 text

Switch cases • Functions with switch statements are likely to do N things. • Switch cases are likely to get scattered throughout the code. • Open ended switch violates OCP.

Slide 25

Slide 25 text

Example • Consider this method of Bird class: 
 double getSpeed() { switch(type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * numberOfCoconuts; case NORWEGIAN_BLUE: return (isNailed) ? 0 : getBaseSpeed(voltage); } }

Slide 26

Slide 26 text

Polymorphism abstract class Bird { abstract double getSpeed() } class European extends Bird { double getSpeed() { return getBaseSpeed(); } } class African extends Bird { double getSpeed() { return getBaseSpeed() - getLoadFactor() * numberOfCoconuts; } } class NorwegianBlue extend Bird { double getSpeed() { return (isNailed) ? 0 : getBaseSpeed(voltage); } } Bird European African Norwegian Blue

Slide 27

Slide 27 text

When switch statements are harmless • When there is no 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.

Slide 28

Slide 28 text

Class / Object

Slide 29

Slide 29 text

Objects • Objects should hide their internal structure. • Follow ‘Tell Don’t Ask’ (Law of Demeter). • Avoid train wrecks - Don’t ask. 
 ((EditSaveCustomizer) master.getModelisable() .getDockablePanel() .getCustomizer()) .getSaveItem().setEnabled(Boolean.FALSE.booleanValue()) ; • Instead tell the object to perform task 
 master.allowSavingOfCustomisations();

Slide 30

Slide 30 text

Classes • Classes should be small. • Small classes follow Single Responsibility Principle (SRP). • Avoid God classes. (Avoid doing everything with single class) • The class should be cohesive.

Slide 31

Slide 31 text

Cohesion • Classes should have a small number of instance 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!

Slide 32

Slide 32 text

SOLID Principles • SRP — Single Responsibility Principle • OCP — Open Closed Principle • LSP — Liskov’s Substitution Principle • ISP — Interface Segregation Principle • DIP — Dependency Inversion Principle

Slide 33

Slide 33 text

Single Responsibility Principle • A class should have only one reason for change

Slide 34

Slide 34 text

Open Closed Principle • A class should be easy to extend without changes

Slide 35

Slide 35 text

Liskov’s Substitution Principle • Subclasses mustn’t change expected behaviour

Slide 36

Slide 36 text

Interface Segregation Principle • Interfaces shouldn’t force classes to implement useless methods

Slide 37

Slide 37 text

Dependency Inversion Principle • High level and low level code should depend on abstractions.

Slide 38

Slide 38 text

Comments

Slide 39

Slide 39 text

Comments • Explain yourself in code 
 // Check to 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())

Slide 40

Slide 40 text

Comments • Comments represent bad code. • If you need comments to understand what the code is doing then the code is poorly written

Slide 41

Slide 41 text

— Brian W. Kernighan and P. J. Plaugher “Don’t comment bad code—rewrite it.”

Slide 42

Slide 42 text

Accepted comments, but not always! • Legal comments • Informative 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

Slide 43

Slide 43 text

Good comments • Explanation of intent 
 public void testConcurrentAddWidgets() 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(); } … } •

Slide 44

Slide 44 text

Bad comments • Mumbling 
 public void loadProperties() { try { 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 } } •

Slide 45

Slide 45 text

Formatting • Good formatting code is important • Follow code style of your organisation. If not present, create one.

Slide 46

Slide 46 text

Exception handling • Use exceptions instead of returning error codes. • 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.

Slide 47

Slide 47 text

Code smells • Long method • solution - Extract method into many smaller auxiliary methods • Large class • solution - Apply single responsibility principle • Duplicate code • Too many parameters • Comments • …

Slide 48

Slide 48 text

Clean tests • One Assert per Test • Single Concept per Test 
 public void testAddMonths(){ SerialDate d1 = SerialDate.createInstance(31, 5, 2004); SerialDate d2 = SerialDate.addMonths(1, d1); assertEquals(30, d2.getDayOfMonth()); assertEquals(6, d2.getMonth()); assertEquals(2004, d2.getYYYY()); }

Slide 49

Slide 49 text

Clean Tests - FIRST • Fast • Run quickly • 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

Slide 50

Slide 50 text

Refactoring • Don’t afraid of changing code to make it better • Always leave the campground cleaner than you found it. — The Boy Scout Rule • Refactor when tests are green (Apply TDD) • Follow DRY