84
Clean Code Péter Jeszenszky Faculty of Informatics, University of Debrecen [email protected] Last modified: April 16, 2019

Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

Clean Code

Péter JeszenszkyFaculty of Informatics, University of Debrecen

[email protected]

Last modified: April 16, 2019

Page 2: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

2

Code Refactoring

● “Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.”– Martin Fowler, Kent Beck, John Brant, William Opdyke,

Don Roberts. Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999.

– Martin Fowler, Kent Beck. Refactoring: Improving the Design of Existing Code. Second Edition. Addison-Wesley, 2018. https://martinfowler.com/books/refactoring.html

Page 3: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

3

Code Smell

● “A code smell is a surface indication that usually corresponds to a deeper problem in the system.”– Martin Fowler. CodeSmell. 9 February 2006.

https://martinfowler.com/bliki/CodeSmell.html

Page 4: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

4

References

● Robert C. Martin. Clean Code: A Handbook of Agile Software Craftsmanship. Prentice Hall, 2008.– Principles, patterns, and practices of writing clean

code– Case studies– Code smells and heuristics

Page 5: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

5Source: Thom Holwerda. WTFs/m. 2008. https://www.osnews.com/story/19266/wtfsm/

Page 6: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

6

What is Clean Code? (1)

● Bjarne Stroustrup:– “I like my code to be elegant and efficient. The logic

should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well.”

Page 7: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

7

What is Clean Code? (2)

● Grady Booch (one of the original developers of UML):– “Clean code is simple and direct. Clean code reads

like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control.”

Page 8: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

8

What is Clean Code? (3)

● Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto)– “Clean code can be read, and enhanced by a developer

other than its original author. It has unit and acceptance tests. It has meaningful names. It provides one way rather than many ways for doing one thing. It has minimal dependencies, which are explicitly defined, and provides a clear and minimal API. Code should be literate since depending on the language, not all necessary information can be expressed clearly in code alone.”

Page 9: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

9

Literate Programming

● Donald E. Knuth. Literate Programming. The Computer Journal, 27 (2): 97–111, 1984. http://www.literateprogramming.com/knuthweb.pdf– „I believe that the time is ripe for significantly better documentation of programs,

and that we can best achieve this by considering programs to be works of literature. Hence, my title: 'Literate Programming.'

– Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.

– The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style. Such an author, with thesaurus in hand, chooses the names of variables carefully and explains what each variable means. He or she strives for a program that is comprehensible because its concepts have been introduced in an order that is best for human understanding, using a mixture of formal and informal methods that reınforce each other.”

Page 10: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

10

Meaningful Names (1)

● Intention-revealing names should be used in the code.– Bad practice:

● int d; // elapsed time in days

– Good practices:● int elapsedTimeInDays;● int daysSinceCreation;● int daysSinceModification;● int fileAgeInDays;

Page 11: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

11

Meaningful Names (2)

● A very bad example:

public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : theList) if (x[0] == 4) list1.add(x); return list1;}

Page 12: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

12

Meaningful Names (3)

● The use of misleading names should be avoided.– For example, the name accountList is

misleading, if it does not refer to a list. If that is the case, the name accountGroup or accounts would be better.

Page 13: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

13

Meaningful Names (4)

● You should use names that can be meaningfully distinguished.– An example of using non-informative names: public static void copyChars(char a1[], char a2[]) { for (int i = 0; i < a1.length; i++) { a2[i] = a1[i]; } }

– Instead, the arguments should be named as source and target, respectively.

Page 14: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

14

Meaningful Names (5)

● Noise words that are too general (e.g., Data, Info, or Object) should be avoided when choosing names.– It is not clear, what the difference is between the

classes named, for example, Product, ProductData and ProductInfo.

– The word variable should never appear in a variable name.

Page 15: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

15

Meaningful Names (6)

● You should use pronounceable names.● You should use searchable names.

– Single-letter names are not easy to locate in the text of the program.

– Single-letter names should be used for local variables inside short methods.

● The length of a name should correspond to the size of its scope.– If a variable or constant might be seen or used in multiple places in

a body of code, it is imperative to give it a search-friendly name.

Page 16: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

16

Meaningful Names (7)

● Encoding type or scope information into names should be avoided.– Examples:

● Hungarian notation https://en.wikipedia.org/wiki/Hungarian_notation

● Prefixing names of members with m_● Prefixing interface names with I

Page 17: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

17

Meaningful Names (8)

● Classes and objects should have noun or noun phrase names.– Examples: Console, FileReader, RandomAccessFile, …

● Methods should have verb or verb phrase names.– Examples: close, readByte, stripTrailingZeros, …

– Names of getters, setters, and predicates should be prefixed with get, set, and is, respectively.

Page 18: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

18

Meaningful Names (9)

● Cuteness should be avoided when choosing names.● Names should be chosen consistently.

– You should always use the same term for the same abstract concept.

● For instance, it’s confusing to have fetch, retrieve, and get as equivalent methods of different classes.

● You should use names that are understood by other programmers.– For example, Computer Science terms, algorithm names, pattern

names, math terms, …● If necessary, you should use names of the problem domain.

Page 19: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

19

Meaningful Names (10)

● Adding meaningful context:– There are a few names which are meaningful in and

of themselves – most are not. Instead, you need to place names in context for your reader by enclosing them in well-named classes, functions, or namespaces.

● When all else fails, then prefixing the name may be necessary as a last resort.

Page 20: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

20

Meaningful Names (11)

● Adding meaningful context (continued):– For example, it is obvious that the variables named street, city, zipCode, and state together form an address.

– However, the variable name state alone does not does not necessarily implies an address.

● We can add context by using prefixes (addrStreet, addrCity, addrZip, addrState). Of course, a better solution is to create a class named Address.

– No more context should be added to a name than is necessary.● For example, the use of prefixes that refer to a specific application

should be avoided.

Page 21: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

21

Functions (1)

● Functions should be very small.– They should not be 100 lines long. They should hardly ever be 20

lines long. Instead, they should be 2–4 lines long.– Blocks within if statements, else statements, while

statements, and so on should be one line long. Probably that line should be a function call.

● Not only does this keep the enclosing function small, but it also adds documentary value because the function called within the block can have a nicely descriptive name.

● This also implies that functions should not be large enough to hold nested structures. Therefore, the indent level of a function should not be greater than one or two. This, of course, makes the functions easier to read and understand.

Page 22: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

22

Functions (2)

● Functions should do one thing. They should do it well. They should do it only.

● One level of abstraction per function:– In order to make sure our functions are doing “one thing”, we need

to make sure that the statements within our function are all at the same level of abstraction.

● Mixing levels of abstraction within a function is always confusing. Readers may not be able to tell whether a particular expression is an essential concept or a detail.

– The Stepdown Rule: the level of abstraction of functions should decrease from top to bottom.

● The code can be read from top to bottom.

Page 23: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

23

Functions (3)

● switch statements:

– It’s hard to make a small switch statement.● Even a switch statement with only two cases is larger

than we would like a single block or function to be. By their nature, switch statements always do N things.

– Unfortunately we can’t always avoid switch statements, but we can make sure that each switch statement is buried in a low-level class and is never repeated.

Page 24: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

24

Functions (4)

● switch statements (continued):– For example, the following function is too large and

does more than one thing. It violates both the Single Responsibility Principle and the Open Closed Principle.

public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateHourlyPay(e); case SALARIED: return calculateSalariedPay(e); default: throw new InvalidEmployeeType(e.type); }}

Page 25: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

25

Functions (5)

● switch statements (continued):

– The solution to this problem is to bury the switch statement using the Abstract Factory design pattern (see the next page).

– General rule:● switch statements can be tolerated if they appear only

once, are used to create polymorphic objects, and are hidden behind an inheritance relationship so that the rest of the system can’t see them.

Page 26: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

26

public abstract class Employee { public abstract boolean isPayday(); public abstract Money calculatePay(); public abstract void deliverPay(Money pay);}

public interface EmployeeFactory { public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;}

public class EmployeeFactoryImpl implements EmployeeFactory { public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType { switch (r.type) { case COMMISSIONED: return new CommissionedEmployee(r) ; case HOURLY: return new HourlyEmployee(r); case SALARIED: return new SalariedEmploye(r); default: throw new InvalidEmployeeType(r.type); } }}

Page 27: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

27

Functions (7)

● Arguments:– The categories of functions by the number of

arguments:● Niladic: functions with no arguments (the ideal case)● Monadic: functions that take a single argument● Diadic: functions that take two arguments● Triadic: functions that take three arguments (should be

avoided)● Polyadic: functions that take more than three arguments

(should not be used at all)

Page 28: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

28

Functions (8)

● Arguments (continued):– Arguments make it harder to understand code.

● They are at a different level of abstraction than the function name and force the reader to know a detail that isn’t particularly important at that point.

– Arguments also complicate testing.

Page 29: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

29

Functions (9)

● Arguments (continued):– Using flag arguments is a bad practice.

● A flag argument is a kind of function argument of type boolean that tells the function to carry out a different operation depending on its value.

– A function that takes such an argument does more than one thing: It does one thing if the flag is true and another if the flag is false!

● See also: Martin Fowler. FlagArgument. 23 June 2011.https://martinfowler.com/bliki/FlagArgument.html

Page 30: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

30

Functions (10)

● Arguments (continued):– For example, Point p = new Point(0,0); is

perfectly reasonable, because the arguments are ordered components of a single value.

● However, it is easy to confuse, for example, the arguments to the assertEquals(expected, actual) JUnit function.

– An example of a reasonable triadic function (JUnit):● assertEquals(double expected, double actual, double epsilon)

Page 31: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

31

Functions (11)

● Arguments (continued):– When a function seems to need more than two or three arguments, it is

likely that some of those arguments ought to be wrapped into a class of their own.

● Example:– Circle makeCircle(double x, double y, double radius);– Circle makeCircle(Point center, double radius);

– Functions with variable number of arguments can be considered as functions that accept a single argument of type list.

● See, for example: java.lang.String.format(String format, Object... args) https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#format(java.lang.String,java.lang.Object...)

● Varargs https://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html

Page 32: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

32

Functions (12)

● Side effects:– Functions should have no side effects.

● They should do only that they promise.

– Output arguments should be avoided.

Page 33: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

33

Functions (13)

● Command query separation:– Functions should either do something or answer something,

but not both.● Either your function should change the state of an object, or it should

return some information about that object.

– Bad practice:● The following function sets the value of a named attribute and returns true if it is successful and false if no such attribute exists:

– public boolean set(String attribute, String value);● For example, it is not clear to the reader what the following statement

means:– if (set("username", "unclebob")) { ... }

Page 34: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

34

Functions (14)

● You should prefer exceptions to returning error codes.– Thus, it is much more easier to introduce additional

exceptions.● New exception classes can be declared as subclasses of

existing exception classes.

Page 35: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

35

Functions (15)

● try/catch blocks should be extracted into functions of their own.– They confuse the structure of the code and mix

error processing with normal processing.– Functions should do one thing. Error handing is one

thing.● The body of a function that handles errors should contain

only a try/catch block.

Page 36: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

36

Functions (16)

● An example of extracting a try/catch block:

public void delete(Page page) { try { deletePageAndAllReferences(page); } catch (Exception e) { logError(e); }}

private void deletePageAndAllReferences(Page page) throws Exception { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey());}

private void logError(Exception e) { logger.log(e.getMessage());}

Page 37: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

37

Functions (16)

● Structured programming:– Functions can contain multiple return statements.

– break and continue statements are allowed in loops.

Page 38: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

38

Comments (1)

● Comments are, at best, a necessary evil.● The proper use of comments is to compensate

for our failure to express ourselves in code.– If our programming languages were expressive

enough, or if we had the talent to subtly wield those languages to express our intent, we would not need comments very much – perhaps not at all.

Page 39: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

39

Comments (2)

● Comments should be avoided, because they lie. Not always, and not intentionally, but too often.

● Code changes and evolves. Unfortunately the comments don’t always follow them – can’t always follow them.– Programmers can’t realistically maintain comments.– The older a comment is, and the farther away it is from the

code it describes, the more likely it is to be just plain wrong.● Inaccurate comments are far worse than no comments

at all.

Page 40: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

40

Comments (3)

● One of the more common motivations for writing comments is bad code.– Rather than spend your time writing the comments

that explain the mess you’ve made, spend it cleaning that mess.

● We should try to avoid comments and express ourselves in code.– Code should be clear and expressive so that it does

not need comments at all.

Page 41: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

41

Good Comments (1)

● Legal comment● Informative comment● Comment explaining intent● Clarification comment● Comment warning of consequences● TODO comment● Amplifying comment● Javadoc comment in a public API

Page 42: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

42

Good Comments (2)

● Informative comment:– Example: java.io.UnixFileSystem (OpenJDK

11):

/* Check that the given pathname is normal. If not, invoke the real normalizer on the part of the pathname that requires normalization. This way we iterate through the whole pathname string only once. */public String normalize(String pathname) { ...}

Page 43: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

43

Good Comments (3)

● Comment explaining intent:– Example: java.util.Collections (OpenJDK

11):

// Suppresses default constructor, ensuring non-instantiability.private Collections() {}

@SuppressWarnings({"rawtypes", "unchecked"})public static void swap(List<?> list, int i, int j) { // instead of using a raw type here, it's possible to capture // the wildcard but it will require a call to a supplementary // private method final List l = list; l.set(i, l.set(j, l.get(i)));}

Page 44: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

44

Good Comments (4)

● Comment explaining intent (continued):– Example: org.apache.commons.lang3.StringUtils (Commons Lang)

public static String normalizeSpace(final String str) { // LANG-1020: Improved performance significantly by normalizing // manually instead of using regex // See // https://github.com/librucha/commons-lang-normalizespaces-benchmark // for performance test ...}

Page 45: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

45

Good Comments (5)

● Clarification comment:– Example: java.lang.Math (OpenJDK 11):

public static float max(float a, float b) { if (a != a) return a; // a is NaN ...}

Page 46: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

46

Good Comments (6)

● Comment warning of consequences:– Example: java.lang.Integer (OpenJDK 11)

public static int parseInt(String s, int radix)throws NumberFormatException {

/* * WARNING: This method may be invoked early during VM * initialization before IntegerCache is initialized. * Care must be taken to not use the valueOf method. */ ...}

Page 47: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

47

Good Comments (7)

● TODO comment:– Example: java.time.format.DateTimeFormatterBuilder (OpenJDK 11)

@Overridepublic boolean format(DateTimePrintContext context, StringBuilder buf) { Long offsetSecs = context.getValue(OFFSET_SECONDS); if (offsetSecs == null) { return false; } String gmtText = "GMT"; // TODO: get localized version of 'GMT' if (gmtText != null) { buf.append(gmtText); } ...}

Page 48: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

48

Good Comments (8)

● TODO comment (continued):– Example: com.google.gson.GsonBuilder

(Gson):

public GsonBuilder setDateFormat(String pattern) { // TODO(Joel): Make this fail fast if it is an invalid date format this.datePattern = pattern; return this;}

Page 49: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

49

Bad Comments (1)

● Mumbling● Redundant comment● Misleading comment● Mandated comment● Journal comment● Noise comment● Position marker● Closing brace comment

● Attributions and bylines● Commented-out code● HTML comment● Nonlocal comment● Comment with too much

information● Comment that is not

obviously related to the code● Javadoc comment in

nonpublic code

Page 50: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

50

Bad Comments (2)

● Mumbling: an obscure comment that means something to the author but others do not understand it.– Example: java.util.Base64 (OpenJDK 11)

@Overridepublic int available() throws IOException { if (closed) throw new IOException("Stream is closed"); return is.available(); // TBD:}

Page 51: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

51

Bad Comments (3)

● Mumbling (continued):– Example: org.apache.commons.io.FileUtils

(Commons IO)

// Private method, must be invoked will a directory parameter

/** * the size of a director * @param directory the directory to check * @return the size */private static long sizeOfDirectory0(final File directory) { ...}

Page 52: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

52

Bad Comments (4)

● Redundant comment: a comment that does not provide additional information about the code, it is not easier to read than the code.

● Misleading comment: a comment that is not precise enough to be accurate.

● Mandated comment: a comment explaining the obvious that is there because every function or variable must have a comment.

● Journal comment: a comment at the beginning of a module that accumulates as a kind of journal, or log, of every change that has ever been made.– Version control systems provide the same functionality.

Page 53: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

53

Bad Comments (5)

● Noise comment: a comment that restates the obvious and provides no new information.– Example:

/** The day of the month. */private int dayOfMonth;

/** * Returns the day of the month. * * @return the day of the month */public int getDayOfMonth() { return dayOfMonth;}

Page 54: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

54

Bad Comments (6)

● Noise comment (continued):– Example: org.apache.commons.lang3.builder.ToStringStyle (Commons Lang)

/** * <p>Constructor.</p> */protected ToStringStyle() { super();}

Page 55: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

55

Bad Comments (7)

● Position marker comment:– Example: java.time.LocalDate (OpenJDK 11):

/** * The day-of-month. */private final short day; //-----------------------------------------------------------------------

Page 56: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

56

Bad Comments (8)

● Position marker comment (continued):– Example: java.util.GregorianCalendar

(OpenJDK 11)

//////////////////// Class Variables//////////////////...

/////////////////////// Instance Variables/////////////////////...

///////////////// Constructors///////////////...

Page 57: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

57

Bad Comments (9)

● Closing brace comment: it may make sense for long functions and blocks with deeply nested structures.– Example: java.text.SimpleDateFormat

(OpenJDK 11)

switch (patternCharIndex) {case PATTERN_ERA: ...case PATTERN_WEEK_YEAR: ...case PATTERN_YEAR: ...case PATTERN_MONTH: ......default: ...} // switch (patternCharIndex)

Page 58: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

58

Bad Comments (10)

● Attributions and bylines: version control systems offer a better alternative.

● Commented-out code: The worst kind of bad comments that should always be avoided. Others who see that commented-out code won't have the courage to delete it. They’ll think it is there for a reason and is too important to delete.– Any part of the code can be deleted without fear

when a version control system is used.

Page 59: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

59

Bad Comments (11)

● Commented-out code (continued):– Example: java.io.RandomAccessFile

(OpenJDK 11)public final void writeByte(int v) throws IOException { write(v); //written++;}public final void writeShort(int v) throws IOException { write((v >>> 8) & 0xFF); write((v >>> 0) & 0xFF); //written += 2;}public final void writeInt(int v) throws IOException { write((v >>> 24) & 0xFF); write((v >>> 16) & 0xFF); write((v >>> 8) & 0xFF); write((v >>> 0) & 0xFF); //written += 4;}

Page 60: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

60

Bad Comments (12)

● HTML comment: HTML in source code makes the comments hard to read.

● Nonlocal comment: a comment that does not apply to the code it appears near, instead, it is describing some other, far distant part of the system.

● Comment with too much information:● Comment that is not obviously related to the

code:● Javadoc comment in nonpublic code:

Page 61: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

61

Formatting

● Source code must be formatted so that is readable.– Readers will get the first impression about the code by

looking at the formatting.● You should choose a set of simple rules that govern

the format of your code, and then you should consistently apply those rules.– If you are working on a team, then the team should agree

to a single set of formatting rules and all members should comply.

● Vertical and horizontal formatting.

Page 62: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

62

Vertical Formatting (1)

● How big should a source file be?– Consider the following empirical study in which the file

lengths have been determined for four software projects:

● Apache Maven 3.6.3 http://maven.apache.org/● Guava 29.0 https://github.com/google/guava● OpenJDK 13.0.1 https://openjdk.java.net/● Wildfly 18.0.1.Final http://wildfly.org/

– The result of the study is shown in a box plot on the next page.

Page 63: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

63

Page 64: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

64

Vertical Formatting (3)

● The newspaper metaphor:– A well-written newspaper article is read from top to bottom.

● At the top you expect a headline that will tell you what the story is about and allows you to decide whether it is something you want to read. The first paragraph gives you a synopsis of the whole story, hiding all the details while giving you the broad-brush concepts. As you continue downward, the details increase.

– We would like a source file to be like a newspaper article.● The name should be simple but explanatory. The name, by itself, should

be sufficient to tell us whether we are in the right module or not. The topmost parts of the source file should provide the high-level concepts and algorithms. Detail should increase as we move downward, until at the end we find the lowest level functions and details in the source file.

Page 65: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

65

Vertical Formatting (4)

● A blank line should identify each new and separate concept.– Blank lines should separate the package

declaration, the import(s), and each of the functions.

Page 66: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

66

Vertical Formatting (5)

// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.// Released under the terms of the CPL Common Public License version 1.0.package fitnesse;

import java.io.IOException;import java.net.Socket;import java.util.concurrent.ExecutorService;

import fitnesse.socketservice.SocketServer;

public class FitNesseServer implements SocketServer { private final FitNesseContext context; private final ExecutorService executorService;

public FitNesseServer(FitNesseContext context, ExecutorService executorService) { this.context = context; this.executorService = executorService; }

@Override public void serve(Socket s) throws IOException { serve(s, 10000); } ...

Page 67: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

67

Vertical Formatting (6)

● Lines of code that are tightly related should appear vertically dense.– There should be no comments or blank lines between them.

● Concepts that are closely related should be kept vertically close to each other.– Closely related concepts should not be separated into different

files unless there is a very good reason.– For those concepts that are so closely related that they belong

in the same source file, their vertical separation should be a measure of how important each is to the understandability of the other.

Page 68: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

68

Vertical Formatting (7)

● Variables should be declared as close to their usage as possible.– Because the functions are very short, local variables should

appear at the top of each function.– Variables for loops should usually be declared within the loop

statement.● Instance variables, on the other hand, should be declared

at the top of the class.● If one function calls another, they should be vertically close,

and the caller should be above the callee, if at all possible.

Page 69: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

69

Horizontal Formatting (1)

● How long should a line be?– Consider the following empirical study in which the

distribution of line lengths has been determined for four software projects:

● Apache Maven 3.6.3 http://maven.apache.org/● Guava 29.0 https://github.com/google/guava● OpenJDK 14.0.1 https://openjdk.java.net/● Wildfly 19.0.0.Final http://wildfly.org/

– The result of the study is shown in a histogram on the next page.

Page 70: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

70

Page 71: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

71

Horizontal Formatting (3)

● Lines should not be too long.– The length of lines should not exceed 120

characters.

Page 72: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

72

Horizontal Formatting (4)

● Weakly related elements should be separated by horizontal white space.– For example, you should put a space at both sides

of an assignment operator. On the other hand, you should not put spaces between function names and the opening parenthesis.

– Example:private void measureLine(String line) { lineCount++; int lineSize = line.length(); totalChars += lineSize; lineWidthHistogram.addLine(lineSize, lineCount); recordWidestLine(lineSize);}

Page 73: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

73

Horizontal Formatting (5)

● You should not align variable names in a set of declarations or values in a set of assignment statements.– For example, the following should be avoided:

package fit;

public class Counts { public int right = 0; public int wrong = 0; public int ignores = 0; public int exceptions = 0;

public Counts(int right, int wrong, int ignores, int exceptions) { this.right = right; this.wrong = wrong; this.ignores = ignores; this.exceptions = exceptions; } ...

Page 74: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

74

Horizontal Formatting (6)

● Proper indentation is very important.– You may use either spaces or tabs for indentation.– You should never break the indentation rule, not

even for short if statements, short while loops, or short functions.

● For example, the following should be avoided:– public int size() { return size; }

Page 75: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

75

Horizontal Formatting (7)

● When the body of a for or while statement is an empty statement, the semicolon should be written in a separate line.– Example:

while ((c = read()) != '\n' && c != '\r' && c >= 0);

should be

while ((c = read()) != '\n' && c != '\r' && c >= 0) ;

Page 76: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

76

Coding Conventions (1)

● See also: coding style, coding standard

Page 77: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

77

Coding Conventions (2)

● Google: Google Style Guides https://google.github.io/styleguide/– Programming languages: Bash, C++, HTML/CSS,

Java, JavaScript, Python, R, …

Page 78: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

78

Coding Conventions (3)

● C:– GNU Coding Standards https://www.gnu.org/prep/standards/standards.html– Linux kernel coding style – The Linux Kernel documentation

https://www.kernel.org/doc/html/latest/process/coding-style.html– Kernighan and Ritchie (K&R)

● C++:– Bjarne Stroustrup. PPP Style Guide.

http://www.stroustrup.com/Programming/PPP-style.pdf● For this book: Bjarne Stroustrup: Programming: Principles and Practice using C++.

Second Edition. Addison-Wesley, 2014.

– Bjarne Stroustrup et al. C++ Core Guidelines https://github.com/isocpp/CppCoreGuidelines

– Google C++ Style Guide https://google.github.io/styleguide/cppguide.html

Page 79: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

79

Coding Conventions (4)

● C#:– C# Coding Conventions (C# Programming Guide)

https://docs.microsoft.com/dotnet/csharp/programming-guide/inside-a-program/coding-conventions

● Java:– Code Conventions for the Java TM Programming Language

https://www.oracle.com/technetwork/java/codeconvtoc-136057.html● Obsolete!

– Google Java Style Guide https://google.github.io/styleguide/javaguide.html● See: https://github.com/google/styleguide/blob/gh-pages/intellij-java-google-style.xml

– Andreas Lundblad. Java Style Guidelines. http://cr.openjdk.java.net/~alundblad/styleguide/index-v6.html

● Python:– Google Python Style Guide https://google.github.io/styleguide/pyguide.html– PEP 8 – Style Guide for Python Code https://www.python.org/dev/peps/pep-0008/

Page 80: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

80

Coding Conventions (5)

● indent (written in: C; license: GPLv3) https://www.gnu.org/software/indent/– A command line tool for formatting C code.– Built-in coding conventions: GNU (-gnu), Linux (-linux), K&R (-kr)

Page 81: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

81

Coding Conventions (6)

● cpplint (written in: Python; license: New BSD License) https://github.com/cpplint/cpplint– A command-line tool to check C/C++ files for style issues

following Google's C++ style guide.● google-java-format (written in: Java; license: Apache

License 2.0) https://github.com/google/google-java-format– A tool that reformats Java source code to comply with Google

Java Style.– Available as a library, a command line tool, and IDE plugins

(IntelliJ IDEA, Eclipse).

Page 82: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

82

Coding Conventions (7)

● Checkstyle (written in: Java; license: LGPLv2.1) https://checkstyle.org/ https://github.com/checkstyle/checkstyle/– A tool to help programmers write Java code that adheres to a

coding standard.– Built-in configuration files are provided for the following

coding conventions:● Oracle (sun_checks.xml)● Google Java Style (google_checks.xml)

– Tool support: https://checkstyle.sourceforge.io/#Active_Tools

Page 83: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

83

Coding Conventions (8)

● EditorConfig https://editorconfig.org/– A file format for defining coding styles.– Supported by numerous editors and IDEs (e.g.,

Eclipse, IntelliJ IDEA, NetBeans).● Natively or via a plugin.

Page 84: Clean Code - arato.inf.unideb.hu · What is Clean Code? (3) Dave Thomas (the coiner of the “DRY” principle, one of the original authors of the Agile Manifesto) – “Clean code

84

Further Recommended Reading

● Robert C. Martin. The Clean Code Blog. https://blog.cleancoder.com/

● Clean Coders https://cleancoders.com/