name: heading layout: true class: center, middle, inverse
Chris Dail
VP Engineering at Motryx
https://chrisdail.com / @chrisdail
background-image: url(images/wtfs-per-min.png)
Chris Dail
VP Engineering at Motryx
https://chrisdail.com / @chrisdail
layout: false
- Repeated Code - Functions?
- Right Tool for the Job - Not Bash!
- Consider Python -
requests
andjson
- Avoid and Handle Errors
- Consider Python -
background-image: url(images/one_week_later.png)
background-image: url(images/three_weeks_later.jpg)
template: heading background-image: url(images/mind_blown.jpg)
background-image: url(images/this_bad_code.jpg) template: heading
template: heading
template: heading
layout: false
-
Decreases productivity over time
-
Hard to maintain --
-
Broken Window Effect
- Bad code causes carelessness
- Leads to more bad code
template: heading
template: heading
template: heading
- Other People
- Reading vs Writing Code
- Easily Understood
- Simple Architecture, Abstractions
- One Thing does One Thing
template: heading
template: heading
- Get it Right the First Time
--
- 'Grand Redesign' that never comes
- Code Reviews: Don't let poor code slip through
-
Industry average is around 15-50 bugs per 1000 lines of code --
-
Writing less code will result in fewer bugs #HeDidTheMath --
-
Cannot do this artificially
- Readability!
- Quality - Fewer lines, more meaningful
- Simple
template: heading
class: bad
- Reveal Intent - what is this thing used for?
AccountPrincipal p;
--
- Meaningful distinctions, avoid "noise words" redundant
RestClient clientToUse = getClient();
--
- Human readable / searchable - No per character cost
String acctNm
--
- Follow standards: like javabean naming in Java.
- Classes/Types: Nouns, meaningful and avoid fluff words .good[
Account
Alert
DailyUsage
AuthorizationPolicy
] .bad[
SystemData
ConfigInfo
Manager
Util
]
- Methods/Functions: Verbs. Function names descriptive and don't be afraid of length .good[
process()
startMonitor()
modifyAccount()
runPlaybookAndWaitComplete()
] .bad[
varsWithTarget()
taskStatusInProgress()
]
class: bad
- Avoid encoding names with: Type, Scope, Visibility or Static
- Hungarian Notation
- This is why we have IDEs and syntax highlighting
ListBox lb_name
private static Logger _log;
private m_name;
Integer nSize;
List<User> usersList;
-
Top 5 worst modules names --
utils
commons
shared
lib
tools
--
-
Alternatives
io
config
encryption
class: bad
- Should do one thing and only one thing
private void validateAndExtractInformationFromZip()
--
-
Be wary of and in function names
-
You can always call another function --
-
Should be short (Keep under 20 lines in most cases)
-
Avoid side effects (getName should not change state)
class: bad
-
Classes should also Do One Thing
-
Single Level of Abstraction --
-
Properties and functions follow the "theme" --
-
Avoid "Junk Drawer" classes
- Avoid magic numbers or magic strings
- Use constants defined in one place
.bad[
if ((i == 0) &&
!((attVal.charAt(i) >= 1 && attVal.charAt(i) <= 31)
|| (attVal.charAt(i) == 33)
|| (attVal.charAt(i) >= 36 && attVal.charAt(i) <= 42)
|| (attVal.charAt(i) >= 45 && attVal.charAt(i) <= 58)
|| (attVal.charAt(i) == 61)
|| (attVal.charAt(i) >= 63 && attVal.charAt(i) <= 91)
|| (attVal.charAt(i) >= 93)
.bad[
const val NUMBER_33 = 33
.good[
const val ASCII_CHAR_EXCLAMATION = 33
]
- Enhance Readability
-
Explain intent of the code
-
Answer Why not What or How --
-
Add comments only when it enhances readability --
-
If you need to explain your code, maybe the code is not clear? --
-
Use TODOs sparingly
class: bad
- Redundant - Is it saying the same thing as the code?
// Checks for null
if (state == null) {
return null; // XXX
}
/**
* Construct an account chargeback context.
*
* @param name The account name
* @param id The account ID
*/
public AccountChargeback(String name, String id) {
super(name, id);
}
class: bad
- Misleading
// Check to see if the order is valid.
// Returns true for valid, false for invalid
public boolean validateOrder(Order order) {
if (!order.isValid()) {
throw new ValidationException("Order is not valid");
}
return true;
}
--
-
Commented Out Code - Version control history --
-
References to bug numbers - Also, version control history
// fix for CP-1234
if (state == null) {
-
Version Control History should be treated like code
-
Readability is important
-
Should read like a story --
-
Good Commit comments
-
Small commits
-
Small pull requests
- Keep files short (Typically less than 300 lines)
- Keep line length short (<120 characters)
- Maximum of 2 levels of indenting in a function in most cases
- Use whitespace to separate 'paragraphs' of code
- Variables declared close to usage as possible
- Instance variables at the top of the class
-
Exceptions should be exceptional --
-
Behave in reasonable ways over throwing errors
- Consider Empty list to show no results --
-
Early return for invalid cases (bouncer pattern)
-
No exception swallowing (empty catch block)
template: heading
--
template: heading background-image: url(images/when-in-rome.jpg)
-
Follow the code style of the codebase you are in
-
Follow the conventions of the language --
-
CamelCase vs snake_case
-
Tabs vs Spaces
-
Be consistent --
-
If you need to reformat code, do so in a standalone commit
"Every piece of knowledge must have a single unambiguous, authoritative representation within a system" - Pragmatic Programmer --
-
Don't Repeat Yourself --
-
Reuse code - Functions, Libraries
-
Redundant comments --
-
Multiple developers teams
- Duplication of validation/util functions
- Centralize and Make reuse easy
- Look for existing code before your write
template: heading background-image: url(images/copy-paste.jpg)
-
Most evil of programming techniques
-
Creates Repetition --
-
Fix bugs in multiple places --
-
You may not fully understand the code being copied --
-
Consider reuse with functions instead
-
Be wary of "clever" code (aka "cute", "magic") --
-
Solutions that are not intuitive may be harder to read
-
Sometimes the more dull, straightforward way is better --
-
Keep in mind the programming level of your team
template: heading
background-image: url(images/computational_thinking.jpg)
template: heading
template: heading
template: heading
template: heading
- Consider open source packages over rolling your own
- Ask if this library is part of your core competencies
- All code is a liability you need to maintain
- Get over your pride
- You may be able to build a great search engine
- Your time may be better used elsewhere
- As few dependencies as required to do the task
- Favor using tools you already have
- Choose the right tool for the job
- How much code do I need to use this?
- bash/sed/awk are poor json parsers
- Fork wisely. Fork only if needed and do it right
- Avoid cherry-picking and committing modified files
- Clean Code - Robert C. Martin
- The Pragmatic Programmer - Andrew Hunt, David Thomas
- Code Complete - Steve McConnell