Writing Readable Code Eddie Haber Sr Developer, Reflexions Data Reflexions on Coding 9.7.2012
Writing Readable Code
Eddie HaberSr Developer, Reflexions Data
Reflexions on Coding9.7.2012
Overview
1. What is Readable Code?
2. Why is it So Important?
3. How Code Gets Unreadable
4. Patterns that Make Code Hard to Read:● Deep Nesting● Unnecessary Generalization● Ambiguous Names● Hard to Follow Flow of Execution● Code Style vs Individualism● Code Comments
5. Best Practices
What is Readable Code?
Source: Head First Labs
What is Readable Code?
Reads like natural language
What is Readable Code?
Reads like natural language
Spaced into digestible chunks like paragraphs
What is Readable Code?
Reads like natural language
Spaced into digestible chunks like paragraphs
Explains Itself
What is Readable Code?
Reads like natural language
Spaced into digestible chunks like paragraphs
Explains Itself
Tells a story: The Spec
Why is it So Important?
Why is it So Important?
Saves you, your team, your client time.
Why is it So Important?
Saves you, your team, your client time.
Memories fade with time.
Why is it So Important?
Saves you, your team, your client time.
Memories fade with time.
Many projects go undocumented. Readable code can be documentation in itself.
Why is it So Important?
Saves you, your team, your client time.
Memories fade with time.
Many projects go undocumented. Readable code can be documentation in itself.
Fewer regression bugs.
Why is it So Important?
Hard-to-read code seems more complex and harder to edit than it really is.
How Code Gets Unreadable
Business logic can be arbitrary, complex, even contradictory.
How Code Gets Unreadable
Polluted over time
Cruft
Inefficient edits
Software applications are the most complex man-made constructs in existence.
Source: scottmccloud.com
Patterns that Make Code Hard to Read
· Deep Nesting
· Unnecessary Generalization
· Ambiguous Names
· Hard to Follow Flow of Execution
· Code Style vs Individualism
· Code Comments
1.Deep NestingPatterns that Make Code Hard to Read
4. Patterns: Deep Nesting
1.Deep Nesting
Nesting is hard to read and edit.
Return early from loops and functions.
Use continue, break, return.
Meat of function ideally at first level of indentation
2.Unnecessary Generalization
Patterns that Make Code Hard to Read
2.Unnecessary Generalization
Never abstract for a single implementation.
2.Unnecessary Generalization
Never abstract for a single implementation.
// 10 lines of code
// that calls a
// gateway once
vs
// a gateway class
// with a single
// implementation
3.Ambiguous NamesPatterns that Make Code Hard to Read
3.Ambiguous Names
Is that string you're about to use to query authors from a SQL table a...
$qry $sql
$select$search
$authors_sql$author_qry
$query_authors$db_query
3.Ambiguous Names
Is the result that comes back a...
$rslt
$authors_list$dbh
$search
$author_result
$response
$auth_dbh$results
3.Ambiguous Names
Be consistent. Use clear simple naming.
$db = new Database_Adapter();
$sql = "SELECT * FROM authors";
$result = $db->query($sql);
$sql (goes to) $db (delivers) $result
3.Ambiguous Names
Sneaky Boolean Variables...
Is it true if failed, or false if failed?
if ($fail_gateway)...
3.Ambiguous Names
Mysterious Boolean Parameters...
send_mail($recipients, $msg, true);
3.Ambiguous Names
Mysterious Boolean Parameters...
Use constants (they're free!) to make codeflow readable...
send_mail($recipients, $msg, true);
const('DELETE_ALL_ACCOUNTS', true);
const('DO_NOT_DELETE_ACCOUNTS', false);
send_mail($recipients, $msg, DELETE_ALL_ACCOUNTS);
3.Ambiguous Names
Avoid excessive abbreviation.
Abbreviations are arbitrary and hard to remember.
3.Ambiguous Names
Avoid excessive abbreviation.
Abbreviations are arbitrary and hard to remember.
Was it...
Be explicit.
$srchBttn ?
$searchBtn ?
$schBtn ?
$srchBtn ?
$search_button
4.Hard to Follow Flow of ExecutionPatterns that Make Code Hard to Read
4.Hard to Follow Flow of Execution
Reading code means following the flow of execution.
4.Hard to Follow Flow of Execution
Transitional variables$string = "Three Card Monte";
$lowercase = strtolower($string);
$ready_for_web = htmlentities($lowercase);
$view->name = $ready_for_web;
4.Hard to Follow Flow of Execution
Transitional variables
Less code = Less reading
$string = "Three Card Monte";
$view->name = htmlentities(strtolower($string));
$string = "Three Card Monte";
$lowercase = strtolower($string);
$ready_for_web = htmlentities($lowercase);
$view->name = $ready_for_web;
4.Hard to Follow Flow of Execution
Status codes and ids in code are mysteries.$order->set_order_type(5);
4.Hard to Follow Flow of Execution
Status codes and ids in code are mysteries.
Use strings or constants for concrete statuses.$order->update_status(OrderStatus::PAID);
$order->set_order_type(5);
4.Hard to Follow Flow of Execution
Status codes and ids in code are mysteries.
Use strings or constants for concrete statuses.
Reference concrete data by string
$order->update_status(OrderStatus::PAID);
$order->set_order_type(5);
$sql = "SELECT * FROM role WHERE id = 1";
$sql = "SELECT * FROM role WHERE role = 'admin';
4.Hard to Follow Flow of Execution
Functions that return arbitrary data:$monster_array = $book->process_authors();
print $monster_array[0]['author']['first_name'];
4.Hard to Follow Flow of Execution
Functions that return arbitrary data:$monster_array = $book->process_authors();
print $monster_array[0]['author']['first_name'];
● Return arrays of objects instead or an iterator
● Make a (documented) class for the return objects
● Sample of the returned data structure in the comment block
5.Code Style vs. Individualism
Patterns that Make Code Hard to Read
5.Code Style vs. Individualism
Camelcase or underscore?
Curly braces with or without conditionals?
Use the formats and conventions of the language or framework you're working with.
5.Code Style vs. Individualism
Funny variable names, comments, and methods.
Just make sure they explain functionality.
$dull_boy = work_all_day($Jack_Torrence);
5.Code Style vs. Individualism
Whitespace is crucially important even when the compiler doesn't mind.
● If tabs, stay with tabs
● If spaces, stay with spaces
● Indent consistently - indentation is a queue for reading
6.Code CommentsPatterns that Make Code Hard to Read
// ping server to make
// sure still running and
// log results
$results = ping($server);
check_results($results);
log_results($results);
exit;
6.Code Comments
Helpful vs. unhelpful comments
// ping the server
$results = ping($server);
// check the results
check_results($results);
// log the results
log_results($results);
// exit
exit;
// check user
vs.
Who are you talking to?
Avoid unhelpful questions in comments
Make comments clear and useful
6.Code Comments
// Why is this even here?
// Magic. Do not touch.
6.Code Comments
Use DocBlock style blocks...
● Over all functions/methods
● Define @params and @returns
● If business rules involved, give a synopsis of what the method does.
6.Code Comments
Source: NetTutsPlus
Best Practices
Best Practices
● Jeuje code● Transitional variables● Return early● Add comments
Refactor! The first pass is usually the least efficient implementation.
Best Practices
Break down large tasks into smaller ones.
● More private and protected "helper" methods.
● Objects format and filter their own output.
Best Practices
DRY - Don't Repeat Yourself. Use libraries and conventions already established
● In the class (method already exists?)
● In the libs (utility already exists?)
● In the framework (component already exists?)
● On the web (website already exists?)
Reflexions on Coding9.7.2012
//
// Dear maintainer:
//
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 42
//