Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
CLEAN CODE
Robert C. Martin Series
Create by: Java.devexpress@gmail.com
ABOUT CLEAN CODE
 Robert C. Martin (Uncle Bob)
 Clean Code
 Why is Clean Code?
 You are programmer
 You want to be a ...
WHAT IS CLEAN CODE?
 Bjarne Stroustup
 I like my code to be elegant and
efficient.
 The logic should be straightforward...
CHAPTER1: WHAT IS CLEAN CODE?
 Dave Thomas
 Clean code can be read.
 It has meaningful names.
 It has unit test and cu...
CHAPTER2: MEANINGFUL NAMES
 Use Intention-Revealing Names
public List<int[]> getThem() {
List<int[]> list1 = new ArrayLis...
CHAPTER2: MEANINGFUL NAMES
 Use Intention-Revealing Names
public List<int[]> getThem() {
List<int[]> list1 = new ArrayLis...
CHAPTER2: MEANINGFUL NAMES
 Avoid Disinformation
int a = l;
if (O == l) {
a = O1;
} else {
l = 01;
}
CHAPTER2: MEANINGFUL NAMES
 Make Meaningful Distinctions
public static void copyChars(char a1[], char a2[]) {
for (int i ...
CHAPTER2: MEANINGFUL NAMES
 Use Pronounceable Names
class DtaRcrd102 {
private Date genymdhms;
private Date modymdhms;
pr...
CHAPTER2: MEANINGFUL NAMES
 Use Searchable Names
for (int j=0; j<34; j++) {
s += (t[j]*4)/5;
}
int realDaysPerIdealDay = ...
CHAPTER2: MEANINGFUL NAMES
 Avoid encodings
public class Part {
private String m_dsc; // The textual description
void set...
CHAPTER2: MEANINGFUL NAMES
 Avoid encodings
for (a = 0; a < 10; a++) {
for (b = 0; b < 10; b++) {
…………..
}
}
for (i = 0; ...
CHAPTER2: MEANINGFUL NAMES
 Class Names
 A class name should not be a verb.
 Classes and objects should have noun or no...
CHAPTER2: MEANINGFUL NAMES
 Method Names
CHAPTER2: MEANINGFUL NAMES
 Add Meaningful Context
// a good solution
firstName, lastName, street, city, state, zipcode
/...
CHAPTER2: MEANINGFUL NAMES
 Don’t Add Gratuitous Context
 Address
// is a fine name for a class
 AccountAddress, Custom...
CHAPTER3: FUNCTION
 Small
 Should be small
 Should be smaller than that
 < 150 characters per line
 < 20 lines
 Do O...
CHAPTER3: FUNCTION
 One Level of Abstraction per Function
 In order to make sure our functions are doing “one
thing,” we...
CHAPTER3: FUNCTION
 Reading Code from Top to Botom
 We want the code to read like a top-down narrative.
 We want every ...
CHAPTER3: FUNCTION
 Switch Statements
 // not good solution
public Money calculatePay(Employee e) throws InvalidEmployee...
 // a better solution
public abstract class Employee {
public abstract boolean isPayday();
public abstract Money calculat...
CHAPTER3: FUNCTION
 Function Argument
 The ideal number of arguments for a function is zero
(niladic).
 Next comes one ...
FUNCTION ARGUMENT
 Common Monadic Forms
 // if a function is going to transform its input argument,
 the transformation...
FUNCTION ARGUMENT
 Argument Objects
 When a function seems to need more than two or three
arguments, it is likely that s...
FUNCTION ARGUMENT
 Argument Lists
 Sometimes we want to pass a variable number of
arguments into a function.
 String.fo...
CHAPTER4: COMMENTS
 Comments Do Not Make Up for Bad Code
 don’t comment bad code, rewrite it!
 Explain Yourself in Code...
CHAPTER4: COMMENTS (STIMULATE)
 Legal Comment
// Copyright (C) 2011 by Osoco. All rights reserved.
// Released under the ...
CHAPTER4: COMMENTS (GOOD)
 Explanation of Intent
 Clarification
//This is our best attempt to get a race condition
//by ...
CHAPTER4: COMMENTS (GOOD)
 Warning of Consequences
 TODO Comment
public static SimpleDateFormat makeStandardHttpDateForm...
CHAPTER4: COMMENTS (BAD)
 Mumbling
try {
String propertiesPath = propertiesLocation + "/" +
PROPERTIES_FILE;
FileInputStr...
CHAPTER4: COMMENTS (BAD)
 Redundant Comment
// Utility method that returns when this.closed is true.
// Throws an excepti...
CHAPTER4: COMMENTS (BAD)
 Mandated Comment
/**
* @param title The title of the CD
* @param author The author of the CD
* ...
CHAPTER4: COMMENTS (BAD)
 Journal Comment
* Changes (from 11-Oct-2001)
* --------------------------
* 11-Oct-2001 : Re-or...
CHAPTER4: COMMENTS (BAD)
 Closing Brace Comment
 Commented-Out Code
while ((line = in.readLine()) != null) {
lineCount++...
CHAPTER4: COMMENTS (BAD)
 HTML Comments
 Nonlocal Information
 Too Much Information
 Unobvious Connection
 Function H...
CHAPTER4: COMMENTS (BAD)
 HTML Comments
 Nonlocal Information
 Too Much Information
 Unobvious Connection
 Function H...
CHAPTER5: FORMATTING
 Vertical Formatting
 Vertical Density
// vertical density implies close association
 Vertical Dis...
CHAPTER5: FORMATTING
 Horizontal Alignment
CHAPTER5: FORMATTING
 Breaking Indentation
 Break after a comma.
 Break after an operator.
 Prefer higher-level breaks...
CHAPTER5: FORMATTING
 Team Rules
 // every programmer has his own favorite formatting rules
 // but if he works in a te...
CHAPTER6: ERROR HANDLING
CHAPTER6: ERROR HANDLING
 Use Exceptions Rather Than Return Codes
CHAPTER6: ERROR HANDLING
 Use Exceptions Rather Than Return Codes
CHAPTER6: ERROR HANDLING
 Write Your Try-Catch-Finally Statement First
@Test(expected = StorageException.class)
public vo...
CHAPTER6: ERROR HANDLING
 Don't Return Null
public void registerItem(Item item) {
if (item != null) {
ItemRegistry regist...
DON'T RETURN NULL
List<Employee> employees = getEmployees();
if (employees != null) {
for(Employee e : employees) {
totalP...
CHAPTER6: ERROR HANDLING
 Don't Pass Null
 Returning null from methods is bad, but passing null into
methods is worse.
p...
DON'T PASS NULL
 Is this better? It might be a little better than a null pointer
exception.
 But remember, we have to de...
CHAPTER1: WHAT IS CLEAN CODE?
 Code simple, efficient
 Logic logic clear
 Dependencies minimal
 Class, method does one...
THE END
Upcoming SlideShare
Loading in …5
×

Clean code slide

1,253 views

Published on

Robert C. Martin

Published in: Software
  • Be the first to comment

Clean code slide

  1. 1. CLEAN CODE Robert C. Martin Series Create by: Java.devexpress@gmail.com
  2. 2. ABOUT CLEAN CODE  Robert C. Martin (Uncle Bob)  Clean Code  Why is Clean Code?  You are programmer  You want to be a better programmer
  3. 3. WHAT IS CLEAN CODE?  Bjarne Stroustup  I like my code to be elegant and efficient.  The logic should be straightforward  The dependencies minimal  Clean code does one thing well. Bjarne Stroustup, người phát minh ra C++ và là tác giả của cuốn The C++ Programming Language
  4. 4. CHAPTER1: WHAT IS CLEAN CODE?  Dave Thomas  Clean code can be read.  It has meaningful names.  It has unit test and customer tests. Dave Thomas cha đẻ của chiến lược Eclipse
  5. 5. CHAPTER2: MEANINGFUL NAMES  Use Intention-Revealing Names public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : theList){ if (x[0] == 4) list1.add(x); } return list1; }
  6. 6. CHAPTER2: MEANINGFUL NAMES  Use Intention-Revealing Names public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : theList) { if (x[0] == 4) list1.add(x); } return list1; } public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell : gameBoard) { if (cell.isFlagged()) flaggedCells.add(cell); } return flaggedCells; }
  7. 7. CHAPTER2: MEANINGFUL NAMES  Avoid Disinformation int a = l; if (O == l) { a = O1; } else { l = 01; }
  8. 8. CHAPTER2: MEANINGFUL NAMES  Make Meaningful Distinctions public static void copyChars(char a1[], char a2[]) { for (int i = 0; i &lt; a1.length; i++) { a2[i] = a1[i]; } }
  9. 9. CHAPTER2: MEANINGFUL NAMES  Use Pronounceable Names class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = “102”; /* ... */ }; class Customer { private Date generationTimestamp; private Date modificationTimestamp; private final String recordId = “102”; /* ... */ };
  10. 10. CHAPTER2: MEANINGFUL NAMES  Use Searchable Names for (int j=0; j<34; j++) { s += (t[j]*4)/5; } int realDaysPerIdealDay = 4; int NUMBER_OF_TASKS = 34; int WORK_DAYS_PER_WEEK = 5; int sum = 0; for (int j=0; j < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks; }
  11. 11. CHAPTER2: MEANINGFUL NAMES  Avoid encodings public class Part { private String m_dsc; // The textual description void setName(String name) { m_dsc = name; } } public class Part { String description; void setDescription(String description) { this.description = description; } }
  12. 12. CHAPTER2: MEANINGFUL NAMES  Avoid encodings for (a = 0; a < 10; a++) { for (b = 0; b < 10; b++) { ………….. } } for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { ………….. } }
  13. 13. CHAPTER2: MEANINGFUL NAMES  Class Names  A class name should not be a verb.  Classes and objects should have noun or noun phrase names like: Customer, WikiPage, Account, and AddressParser.  Avoid words like: Manager, Processor, Data, or Info in the name of a class.
  14. 14. CHAPTER2: MEANINGFUL NAMES  Method Names
  15. 15. CHAPTER2: MEANINGFUL NAMES  Add Meaningful Context // a good solution firstName, lastName, street, city, state, zipcode // a better solution addrFirstName, addrLastName, addrState // a best solution Class Address
  16. 16. CHAPTER2: MEANINGFUL NAMES  Don’t Add Gratuitous Context  Address // is a fine name for a class  AccountAddress, CustomerAddress // are fine names for instances of the class Address // but could be poor names for classes  MAC addresses, port addresses, Web addresses // not good solution  PostalAddress, MAC, URI // a better solution
  17. 17. CHAPTER3: FUNCTION  Small  Should be small  Should be smaller than that  < 150 characters per line  < 20 lines  Do One Thing  // FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL.  // THEY SHOULD DO IT ONLY. public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception { if (isTestPage(pageData)) { includeSetupAndTeardownPages(pageData, isSuite); } return pageData.getHtml(); }
  18. 18. CHAPTER3: FUNCTION  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.  // high level of abstraction getHtml()  // intermediate level of abstraction String pagePathName = PathParser.render(pagePath);  // remarkably low level .append("n")
  19. 19. CHAPTER3: FUNCTION  Reading Code from Top to Botom  We want the code to read like a top-down narrative.  We want every function to be followed by those at the next level of abstraction so that we can read the program, descending one level of abstraction at a time as we read down the list of functions. => I call this The Stepdown Rule.
  20. 20. CHAPTER3: FUNCTION  Switch Statements  // not good solution 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); } }
  21. 21.  // a better solution 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 … ; } public class EmployeeFactoryImpl implements EmployeeFactory { public Employee makeEmployee(EmployeeRecord r) throws … { 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); } } }
  22. 22. CHAPTER3: FUNCTION  Function Argument  The ideal number of arguments for a function is zero (niladic).  Next comes one (monadic), followed closely by two (dyadic).  Three arguments (triadic) should be avoided where possible.  More than three (polyadic) requires very special justification and then shouldn’t be used anyway.
  23. 23. FUNCTION ARGUMENT  Common Monadic Forms  // if a function is going to transform its input argument,  the transformation should appear as the return value  // not good StringBuffer transform(StringBuffer in)  // is better than void transform(StringBuffer out)
  24. 24. FUNCTION ARGUMENT  Argument Objects  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.  // is more than two arguments makeCircle(double x, double y, double radius);  // to be wrapped into a class Circle makeCircle(Point center, double radius);
  25. 25. FUNCTION ARGUMENT  Argument Lists  Sometimes we want to pass a variable number of arguments into a function.  String.format("%s worked %.2f hours.", name, hours);  public String format(String format, Object... args)
  26. 26. CHAPTER4: COMMENTS  Comments Do Not Make Up for Bad Code  don’t comment bad code, rewrite it!  Explain Yourself in Code // Check to see if the employee is eligible for full benefits if (employee.flags && employee.age > 65) { if (employee.isEligibleForFullBenefits()) { ……… } }
  27. 27. CHAPTER4: COMMENTS (STIMULATE)  Legal Comment // Copyright (C) 2011 by Osoco. All rights reserved. // Released under the terms of the GNU General Public License // version 2 or later.  Informative Comment // huanlt 20150930 renaming the function:responderBeingTested // Returns an instance of the Responder being tested. protected abstract Responder responderInstance(); // format matched kk:mm:ss EEE, MMM dd, yyyy Pattern timeMatcher = Pattern.compile( "d*:d*:d* w*, w* d*, d*");
  28. 28. CHAPTER4: COMMENTS (GOOD)  Explanation of Intent  Clarification //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, text, failFlag); Thread thread = new Thread(widgetBuilderThread); thread.start(); } assertTrue(a.compareTo(b) == -1); // a < b assertTrue(b.compareTo(a) == 1); // b > a
  29. 29. CHAPTER4: COMMENTS (GOOD)  Warning of Consequences  TODO Comment public static SimpleDateFormat makeStandardHttpDateFormat() { //SimpleDateFormat is not thread safe, //so we need to create each instance independently. SimpleDateFormat df = new SimpleDateFormat("dd MM yyyy"); df.setTimeZone(TimeZone.getTimeZone("GMT")); return df; } //TODO-MdM these are not needed // We expect this to go away when we do the checkout model
  30. 30. CHAPTER4: COMMENTS (BAD)  Mumbling try { String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE; FileInputStream propertiesStream = new FileInputStream(propertiesPath); loadedProperties.load(propertiesStream); } catch(IOException e) { // No properties files means all defaults are loaded }
  31. 31. CHAPTER4: COMMENTS (BAD)  Redundant Comment // Utility method that returns when this.closed is true. // Throws an exception if the timeout is reached. public synchronized void waitForClose (final long timeoutMillis) throws Exception { if(!closed) { wait(timeoutMillis); if(!closed) throw new Exception("MockResponseSender could not be closed"); } }
  32. 32. CHAPTER4: COMMENTS (BAD)  Mandated Comment /** * @param title The title of the CD * @param author The author of the CD * @param tracks The number of tracks on the CD * @param durationInMinutes The duration of the CD in minutes */ public void addCD(String title, String author, int tracks, int durationInMinutes) { CD cd = new CD(); cd.title = title; cd.author = author; cd.tracks = tracks; cd.duration = durationInMinutes; }
  33. 33. CHAPTER4: COMMENTS (BAD)  Journal Comment * Changes (from 11-Oct-2001) * -------------------------- * 11-Oct-2001 : Re-organised the class and moved it to new * package com.jrefinery.date (DG); * 05-Nov-2001 : Added a getDescription() method, and * eliminated NotableDate class (DG); * 12-Nov-2001 : IBD requires setDescription() method, now * that NotableDate class is gone (DG); Changed * getPreviousDayOfWeek(), * getFollowingDayOfWeek() and * getNearestDayOfWeek() to correct bugs (DG); * 05-Dec-2001 : Fixed bug in SpreadsheetDate class (DG); * 29-May-2002 : Moved the month constants into a separate * interface (MonthConstants) (DG);
  34. 34. CHAPTER4: COMMENTS (BAD)  Closing Brace Comment  Commented-Out Code while ((line = in.readLine()) != null) { lineCount++; charCount += line.length(); String words[] = line.split("W"); wordCount += words.length; } //while InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); // response.setContent(reader.read(formatter.getByteCount()));
  35. 35. CHAPTER4: COMMENTS (BAD)  HTML Comments  Nonlocal Information  Too Much Information  Unobvious Connection  Function Headers  // short functions don’t need much description  Javadocs in Nonpublic Code  // extra formality of the javadoc comments
  36. 36. CHAPTER4: COMMENTS (BAD)  HTML Comments  Nonlocal Information  Too Much Information  Unobvious Connection  Function Headers  // short functions don’t need much description  Javadocs in Nonpublic Code  // extra formality of the javadoc comments
  37. 37. CHAPTER5: FORMATTING  Vertical Formatting  Vertical Density // vertical density implies close association  Vertical Distance // variables should be declared as close to their usage as possible // instance variables should be declared at the top of the class // dependent functions if one function calls another, they should be vertically close, and the caller should be above the called // conceptual affinity certain bits of code want to be near other bits
  38. 38. CHAPTER5: FORMATTING  Horizontal Alignment
  39. 39. CHAPTER5: FORMATTING  Breaking Indentation  Break after a comma.  Break after an operator.  Prefer higher-level breaks to lower-level breaks.
  40. 40. CHAPTER5: FORMATTING  Team Rules  // every programmer has his own favorite formatting rules  // but if he works in a team  // then the team rules
  41. 41. CHAPTER6: ERROR HANDLING
  42. 42. CHAPTER6: ERROR HANDLING  Use Exceptions Rather Than Return Codes
  43. 43. CHAPTER6: ERROR HANDLING  Use Exceptions Rather Than Return Codes
  44. 44. CHAPTER6: ERROR HANDLING  Write Your Try-Catch-Finally Statement First @Test(expected = StorageException.class) public void retrieveSectionShouldThrowOnInvalidFileName() { sectionStore.retrieveSection("invalid - file"); } public List<RecordedGrip> retrieveSection(String sectionName) { try { FileInputStream stream = new FileInputStream(sectionName); stream.close(); } catch (FileNotFoundException e) { throw new StorageException("retrieval error”, e); } finally { stream.close(); } return new ArrayList<RecordedGrip>(); }
  45. 45. CHAPTER6: ERROR HANDLING  Don't Return Null public void registerItem(Item item) { if (item != null) { ItemRegistry registry = peristentStore.getItemRegistry(); if (registry != null) { Item existing = registry.getItem(item.getID()); if(existing != null){ if (existing.getBillingPeriod().hasRetailOwner()) { existing.register(item); } } } } }
  46. 46. DON'T RETURN NULL List<Employee> employees = getEmployees(); if (employees != null) { for(Employee e : employees) { totalPay += e.getPay(); } } List<Employee> employees = getEmployees(); for(Employee e : employees) { totalPay += e.getPay(); } public List<Employee> getEmployees() { if( .. there are no employees .. ) return Collections.emptyList(); } If you code this way, you will minimize the chance of NullPointerExceptions and your code will be cleaner.
  47. 47. CHAPTER6: ERROR HANDLING  Don't Pass Null  Returning null from methods is bad, but passing null into methods is worse. public class MetricsCalculator { public double xProjection(Point p1, Point p2) { return (p2.x – p1.x) * 1.5; } } public double xProjection(Point p1, Point p2) { if (p1 == null || p2 == null) { throw InvalidArgumentException ("Invalid argument for MetricsCalculator.xProjection"); } return (p2.x – p1.x) * 1.5; }
  48. 48. DON'T PASS NULL  Is this better? It might be a little better than a null pointer exception.  But remember, we have to define a handler for InvalidArgumentException. public class MetricsCalculator { public double xProjection(Point p1, Point p2) { assert p1 != null : "p1 should not be null"; assert p2 != null : "p2 should not be null"; return (p2.x – p1.x) * 1.5; } } The rational approach is to forbid passing null by default.
  49. 49. CHAPTER1: WHAT IS CLEAN CODE?  Code simple, efficient  Logic logic clear  Dependencies minimal  Class, method does one thing well  Meaningful names  Error handling  Comments  Rename code before commit  Refractor code before commit  Format code before commit  Unit test
  50. 50. THE END

×