Nov 8, 2011

The Art of Readable Code - D. Boswell and T. Foucher

  • Attach important details to variable names - for example, append _ms to a variable whose value is in milliseconds or prepend raw_ to an unprocessed variable that needs escaping.
  • Use longer names for larger scopes - don’t use cryptic one- or two-letter names for variables that span multiple screens; shorter names are better for variables that span only a few lines.

Word Alternatives

send - deliver, dispatch, announce, distribute, route
find - search, extract, locate, recover
start - launch, create, begin, open
make - create, set up, build, generate, compose, add, new

Avoid generic names like tmp and retval, unless there’s a specific reason to use them.

Values with Units

Start(int delay) - delay - delay_secs
CreateCache(int size) - size - size_mb
ThrottleDownload(float limit) - limit - max_kbps
Rotate(float angle) - angle - degrees_cw

Encoding Security Attributes

This technique of attaching extra information to a name isn’t limited to values with units. You should do it any time there’s something dangerous or surprising about the variable.

For example, many security exploits come from not realizing that some data your program receives is not yet in a safe state. For this, you might want to use variable names like untrustedUrl or unsafeMessageBody. After calling functions that cleanse the unsafe input, the resulting variables might be trustedUrl or safeMessageBody.
  • A password is in “plaintext” and should be encrypted before further processing - password- plaintext_password 
  • A user-provided comment that needs escaping before being displayed - comment - unescaped_comment 
  • Bytes of html have been converted to UTF-8 - html - html_utf8 
  • Incoming data has been “url encoded” - data - data_urlenc

Coments Markers

TODO: Stuff I haven’t gotten around to yet
FIXME: Known-broken code here
HACK: Admittedly inelegant solution to a problem
XXX: Danger! major problem here

Variables and readability

  • Reduce the scope of each variable to be as small as possible. Move each variable to a place where the fewest lines of code can see it. Out of sight is out of mind.
  • Prefer write-once variables. Variables that are set only once (or const, final, or otherwise immutable) make code easier to understand.

Reorganizing Your Code

  • Separate the generic code from the project-specific code.
  • Code should be organized so that it’s doing only one task at a time.
  • Avoid writing new lines of code by:
    • Eliminating nonessential features from your product and not overengineering
    • Rethinking requirements to solve the easiest version of the problem that still gets the job done
    • Staying familiar with standard libraries by periodically reading through their entire APIs

Testing and Readability

  • Implementing Custom “Minilanguages
  • Use the simplest test inputs that completely exercise your code.
  • Give your test functions a fully descriptive name so it’s clear what each is testing. Instead of Test1(), use a name like Test_<FunctionName>_<Situation>.

No comments: