18
CLEAN CODE “A Handbook of Agile Software Craftsmanship”

Clean code

Embed Size (px)

Citation preview

Page 1: Clean code

CLEAN CODE“A Handbook of Agile Software Craftsmanship”

Page 2: Clean code

Meaningful Names

Page 3: Clean code

Meaningful Names

“Variables should be named with the same level of care given to naming a newborn child”

Use pronounceable namesgenymdhms

Use searchable namesLength of a name should correspond to the

size of its scope Avoid disinformation

Inconsistent spellings

Page 4: Clean code

Meaningful Names

Make meaningful distinctionsWriting code solely to appease the compilerNoise words Product/ProductInfo/ProductData

Use intention-revealing namesWhy does it exist?What does it do?How is it used?

One word per concept...but don’t pun Don’t add gratuitous context

Page 5: Clean code

Functions

Page 6: Clean code

Functions Small

Smaller○ Smaller than that

if/else/while: 1 line blocks Do One Thing

Problem: What is “one thing”?○ “If a function does only those steps that are one level

below the stated name of the function, then the function is doing one thing”

○ “A function is doing more than one thing if you can extract another function from it with a name that is not merely a restatement of its implementation”

Sections within functions – obviously doing more than one thing

Page 7: Clean code

Functions The stepdown rule

Top-down narrative switch statements – always do N things

Should appear only once to create polymorphic objects, hidden from rest of system

Function argumentsIdeal # of arguments: 0includeSetupPage() easier to understand

than includeSetupPageInto(newPagecontent)

If the input’s going to be transformed, it should be returned

Page 8: Clean code

Functions

Flag argumentsImmediately imply that the function does

more than one thing! Command query separation

Either change the state of an object, or return some information about that object

Extract try/catch blocksAllows you to understand, then ignore, error

processingError handling is one thing!

Page 9: Clean code

Comments

Page 10: Clean code

Comments

“Comments are always failures”Compensate for failure to express in code

They lie – we can’t realistically maintain them

Explain yourself in code // Check to see if the employee is eligible for

full benefitsif ((employee.flags & HOURLY_FLAG) &&

(employee.age > 65))vs.

if (employee.isEligibleForFullBenefits())

Page 11: Clean code

Comments Good comments

Informative Explain of intent Clarification – when it’s code you can’t alter Warning of consequences

Bad comments Redundant Misleading Mandated Journal comments Noise comments (“Default constructor”) Closing brace comments Commented-out code HTML comments Nonlocal information TMI Javadocs in nonpublic code

Page 12: Clean code

FormattingpublicDataPair[] getHotelInformation(String hotelId, String informationId)                                      {                                        return getHotelInfo("EN", hotelId, informationId);                                      }

publicDataPair[] getHotelInformation(String lang, String hotelId, String informationId)                                      {

                           String key = "_HOINF_"+lng+"_"+hotelId+"_"+informationId;                       DataPair[] tbl = (DataPair[])csh.getObject(key);                         if(tbl!=null)  return tbl;

                        Connection cn = null;           OracleCallableStatement cs = null;                                  try {                           String qry = " begin HotelServices.getHotelInfo(?, ?, ?, ?, ?); end; ";                               logger . debug("---"+qry+" "+hotelId+" "+informationId);                                   cn = DriverManager.getConnection("jdbc:weblogic:pool:oraclePool",null);                                   cs = (OracleCallableStatement)cn.prepareCall(qry);                                   cs . registerOutParameter(1,java.sql.Types.INTEGER);                                   cs . registerOutParameter(2,java.sql.Types.OTHER);                                   cs . setString(3,hotelId);                                   cs . setString(4,informationId);                                   cs . setString(5,lang);                                   cs . execute();                              int sta = cs.getInt(1);                            if(sta!=0)  throw new Exception("status not zero sta="+sta);                         ResultSet rs = cs.getResultSet(2);                                  tbl = getDataPairArray(rs);                               logger . debug("sta="+sta+" key="+key+" cn="+cn);                                  csh . put(key,tbl);                                      }                                 catch(Exception e)                                      {                               logger . debug("!!! "+e.toString()+" "+key);                                      }                               finally                                      {                                  try {                      if(cs!=null) cs . close();                      if(cn!=null) cn . close();                                      }                                 catch(Exception x)                                      {                               logger . debug("!!! "+x.toString()+" "+key);                               logger . error("!!! "+x.toString());                                      }                                      }                                return tbl;                                      } 

“Eastern Polish Christmas Tree Notation”

Page 13: Clean code

Formatting

Small files usually easier to understand than large files

Newspaper metaphorDetail should increase as we move

downward Vertical openness between concepts Vertical density & closeness implies

close association Horizontal openness

Accentuate operator precedence?

Page 14: Clean code

Objects and Data Structures

Page 15: Clean code

Objects and Data Structures Objects: hide data behind abstractions

and expose functions that operate on that dataOO code: easy to add new classes; hard to

add new functions Data structures: expose their data and

have no meaningful functionsProcedural code: easy to add new functions;

hard to add new data structures

Page 16: Clean code

Objects and Data Structures Law of Demeter: module shouldn’t know

about the innards of the objects it manipulatesDon’t expose internal structure through accessors

“Train wrecks” final String outputDir =

ctxt.getOptions().getScratchDir().getAbsolutePath();

HybridsFunctions that do significant things, but also public

variables/accessorsHard to add both new functions and new data

structuresLeads to feature envy

Page 17: Clean code

Error handling

If it obscures logic, it’s wrong Exceptions rather than return codes Use unchecked exceptions

Checked: low level changes propagate upBreaks encapsulation

Wrap 3rd-party APIs Don’t return null – throw exception or

return a special-case object Don’t pass null

Page 18: Clean code

Classes

...should also be smallIn terms of responsibilities

SRP – should have ONE reason to change

Big # of small classes vs. Small # of large classes

Cohesion OCP – open for extension, closed for

modification