clean code - arato.inf.unideb.hu · what is clean code? (3) dave thomas (the coiner of the...
TRANSCRIPT
Clean Code
Péter JeszenszkyFaculty of Informatics, University of Debrecen
Last modified: April 16, 2019
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
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
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
5Source: Thom Holwerda. WTFs/m. 2008. https://www.osnews.com/story/19266/wtfsm/
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.”
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.”
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.”
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.”
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;
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;}
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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); }}
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.
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); } }}
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)
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.
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
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)
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
32
Functions (12)
● Side effects:– Functions should have no side effects.
● They should do only that they promise.
– Output arguments should be avoided.
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")) { ... }
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.
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.
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());}
37
Functions (16)
● Structured programming:– Functions can contain multiple return statements.
– break and continue statements are allowed in loops.
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.
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.
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.
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
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) { ...}
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)));}
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 ...}
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 ...}
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. */ ...}
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); } ...}
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;}
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
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:}
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) { ...}
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.
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;}
54
Bad Comments (6)
● Noise comment (continued):– Example: org.apache.commons.lang3.builder.ToStringStyle (Commons Lang)
/** * <p>Constructor.</p> */protected ToStringStyle() { super();}
55
Bad Comments (7)
● Position marker comment:– Example: java.time.LocalDate (OpenJDK 11):
/** * The day-of-month. */private final short day; //-----------------------------------------------------------------------
56
Bad Comments (8)
● Position marker comment (continued):– Example: java.util.GregorianCalendar
(OpenJDK 11)
//////////////////// Class Variables//////////////////...
/////////////////////// Instance Variables/////////////////////...
///////////////// Constructors///////////////...
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)
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.
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;}
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:
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.
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.
63
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.
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.
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); } ...
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.
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.
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.
70
71
Horizontal Formatting (3)
● Lines should not be too long.– The length of lines should not exceed 120
characters.
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);}
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; } ...
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; }
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) ;
76
Coding Conventions (1)
● See also: coding style, coding standard
77
Coding Conventions (2)
● Google: Google Style Guides https://google.github.io/styleguide/– Programming languages: Bash, C++, HTML/CSS,
Java, JavaScript, Python, R, …
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
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/
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)
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).
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
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.
84
Further Recommended Reading
● Robert C. Martin. The Clean Code Blog. https://blog.cleancoder.com/
● Clean Coders https://cleancoders.com/