Variables
What's in a name?
- Intention
- No cryptic names
- No abbreviations
- Rather have something longer, but clearer/obvious
- Be serious
- Funny comments etc
//Not clear
for(i=1; i<=ArrayLen(myArr); i++)
- Minimize use
- If possible, just don't use them
- Simple conditions
- Break it up
- Avoid nesting
- Don't assume a branch will run
If you can't look at a piece of code and tell what it can do in under 10 seconds, think about re-writing.
The following just gets too confusing. Try not to have so many conditions in one if statement, break it up.
if(currentUser.isActive()
&& Len(form.content)
&& isValid(form.email)
&& currentUser.isHappy()
)
{
//do something
}
Seperate out the code so you don't get lost in the if/else statments...
if (isMessageReady( form ) )
{
//20 lines of
// send email
//code
}
else if ( !isMessageReady ( form ) )
{
//20 more
//lines
//of code
}
Change to this..
if (isMessageReady( form ) )
{
sendMessage( form )
}
else if ( !isMessageReady ( form ) )
{
handleMessageError( form )
}
Switch / Case
- Minimize Use
- Breaking it up
- Avoid Nesting
- Don't assume a case will match
Looping
- Break up logic
- Avoid nesting
for ( thisPreference in preferences )
{
if ( !thisPreference.isDefaultPreference() )
{
updatePreference.preferences( preferences[this] );
}
else
updatePreference.preferences( preferences[this] );
}
}
for (thisPrefernce in preferences )
{
updatePreference.preferences( preferences[this] );
updatePreference.preferences( preferences[this] );
}
Basically, make the code you're writing more clear to read and handle extra stuff in their own methods..
Methods and Functions
Verb-oriented Names
- updateRSSFeed()
- validate()
- trackShipment()
- authenticate()
- findRelatedProducts()
Methods - Smaller = better
- More cohesive
- Easier to test
- Easier to override
Focus!
- Sergeants and privates
- One public function that gets called from the outside (to a CFC for example), but within that its a bunch of private methods that get called.
- One level of abstraction
Try not to argue
- Avoid many arguments
- Best number is 0, then 1, then 2... After that it gets too many / too complicated
- Avoid optional arguments
- Add a class to encapsulate arguments
// 1+3^2 = 10 possible invocations
function loadContent ( url, isSSL=false, useCache=false, method='get' )
function loadContent ( LoaderSettings settings )
Where you're passing a cfc as an argument, if it makes things more clear of simple
Side Effects:
What just happened?
- Avoid side effects
- Return a value vs changing things
- Throwing things into a method and having it updating things, return things back to make it more clear
Error Codes
- Codes are evil
- Codes can change
- Exceptions are there for a reason!
Classes (and CFCs)
Noun-Oriented Names
- Shipment
- Attendee
- Permission
- UserGateway
- RemoteContentService
- InvoiceGenerator
Rather have more smaller, cohesive cfcs vs really long ones
3-4 screens tall is really big..
Cohesive
- Does one thing
- Simpler
- Easier to test
Guard that Wall!
- Encapsulate by convention, reveal by need
- Be paranoid up front, make all private and expose them as you need them..
- Limit external dependencies
- The more things something depends on, the more change a chance will occur and negatively affect things.
Comments
Don't Comment
- All comments are failures
- Code is not simple enough or the language is not useful enough to allow for you to be clear.
- Ask yourself WHY you think you need a comment
- Try to make the code simpler and more readable before using comments.
If you HAVE to, make it count
- Don't restate HOW the code works
- /* Loop over users query, then set firstName from db record */
- Explain WAHT the code is supposed to do
Don't Comment Out Code
- Comments should not be version control
- Nobody ever deletes it and will forget why its there for still..
- All it offers is confusion
Joined at the Hip
- Stale comments are far worse than no comments
- Obligated to freshness
- If you put a comment, you're obligated to keep that block of comment fresh and relevant.
- Again, try to make the code more useful first.
Format and Layout
How do you lay the code out physically?
Adopt a Standard
Vertical Spacing
- Make it easy to scan through
- Seperate methods
- Separate appropriate chunks of logic
- Litmus test for complexity
Put some spaces here and there to visually break things up..
Indentation
- Again, easy to read
- Easy to identify conditionals, loops etc
- Litmus test for complexity
- If it goes too far over, you'll start to know it may be getting too complex
You Are Your Code
Conclusion
Clean Code Matters
- Clean code is easier to read
- Clean code is easier to maintain
- Clean code encourages thoughtful design
Some reading:
Clean Code: A Handbook of Agile Software Craftsmanship
The Pragmatic Programmer