10 Ways to Write Clean Code

There Will be Code

“Code is the language in which we ultimately express the requirements. We may create languages that are closer to the requirements. We may create tools that help us parse and assemble those requirements into formal structures. But we will never eliminate necessary precision—so there will always be code.”

Robert C. Martin, Engineer & Author of ‘Clean Code: A Handbook of Agile Software Craftmanship’

 The Curse of Bad Code

If you have been a programmer for any significant amount of time, you and/or your team have run into and been slowed down by someone else’s messy (aka “bad”) code. The consequences of such slowdowns can be significant. Over the span of a year or two, even the most nimble of teams can be stopped in their tracks by problematic code.

When you find every change you make to the code breaks two or three other parts of the code – the concept of trivial changes flies out the window. Every addition or modification to the system requires that the tangles, twists, and knots be “understood” so that more tangles, twists, and knots can be added. Throw a few necklaces into a ziploc bag, shake it up, and then try to separate the chains–it’s like that. Over time the unresolved core issues run so deep, there’s no way to clean it up.

What is Clean Code?

There are many definitions of clean code floating around, but the most beautiful definition comes from Bjarne Stroustrup (inventor of C++ and author of The C++ Programming Language),

 “I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well.”

 Bjarne elevates the value of code hygienics. Clean code creates a pleasing experience similar to that of a well-crafted music box or well-designed car. Diving deeper into this characterization of code, Bjarne mentions efficiency—twice. Not surprising coming from the inventor of C++; but there’s more to it than the sheer desire for speed. Wasted cycles are the opposite of elegant, they are not pleasing.

 In using the word “tempt,” Bjarne exposes a deeper truth around the tendency to “just keep going.” Bad code tempts the mess to grow because when devs change the bad code (with good intentions), it only compounds the problem.

 Take Steps Toward Clean Code

 So how can you transform bad code into clean code? Here are some actions you can take to drive things in the right direction:

1. Define Class Names as Nouns

Classes and objects should be noun or phrase names like Customer, Account etc. Avoid words like Manager, Processor, Data, Info, or using verbs in the name of a class.

2. Clarify Function Names with Verbs

 Methods should have a verb or verb phrase names like postPayment, deletePage, or save. Accessors, mutators, and predicates should be named for their value and prefixed with get, set, and is.

String name = customer.getName();
customer.setName("john");
if (customer.isRegistered())...

When constructors are overloaded, use static factory methods with names that describe the arguments. For example,

Complex fulcrumPoint = Complex.FromRealNumber(23.0);

is generally better than

Complex fulcrumPoint = new Complex(23.0);

Consider enforcing this usage by making the corresponding constructors private.

3. Pick One Word per Concept

 Pick one word for one abstract concept and stick with it. For instance, it’s confusing to have fetch, retrieve, and get as equivalent methods of different classes. How do you remember which method name goes with which class? Sadly, you often have to remember which company, group, or individual wrote the library or class in order to remember which term was used. Otherwise, you spend an awful lot of time browsing through headers and previous code samples.

4. Encapsulate Conditionals

Boolean logic is hard enough to understand without having to see it in the context of an if or while statement. Extract functions that explain the intent of the conditional.

For example:

if (shouldBeDeleted(timer))

is preferable to  

if (timer.hasExpired() && !timer.isRecurrent())

5. Keep Functions Focused on Doing One Thing–Very Well 

Look at this example:

if (includeSuiteSetup) {

WikiPage suiteTeardown = PageCrawlerImpl.getInheritedPage( SuiteResponder.SUITE_TEARDOWN_NAME, wikiPage);

if (suiteTeardown != null) {
WikiPagePath pagePath = suiteTeardown.getPageCrawler().getFullPath(suiteTeardown);
String pagePathName = PathParser.render(pagePath); buffer.append("!include -teardown .").append(pagePathName) .append("\n");
} } }

pageData.setContent(buffer.toString()); return pageData.getHtml();
}

Did  you understand the function after a few minutes of studying this? Probably not. There’s too much going on  at too many different levels of abstraction. There are strange strings and odd function calls mixed in with doubly nested if statements controlled by flags. 

However, with just a few simple method extractions, some renaming, a little restructuring, we were able to capture the intent of the function in the few lines of Listing

public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception {

if (isTestPage(pageData))
  includeSetupAndTeardownPages(pageData, isSuite);

return pageData.getHtml();
}

6. Avoid Passing Flags to Functions 

Flag arguments are ugly. Passing a boolean into a function is a terrible practice. It immediately complicates the signature of the method, loudly proclaiming that this function does more than one thing. It does one thing if the flag is true, and another if the flag is false!

Ugly:

showProgressBar(true)
showProgressBar(false)

Clean: 

showProgressBar()
hideProgressBar()

7. Use Fewer Arguments 

Passing a few arguments makes a function simpler to understand and easy to write test cases.

For example:

myFunction(float x, float y) 

Can be simplified to: 

myFunction(Points coordinates)

8. Use Exceptions Instead of Error Codes 

 The problem with these approaches is that they clutter the caller. The caller must check for errors immediately after the call and, unfortunately, it’s easy to forget. For this reason, it is better to throw an exception when you encounter an error. The calling code is cleaner, and its logic is not obscured by error handling.

Bad practice:

public class DeviceController { ...
public void sendShutDown() { DeviceHandle handle = getHandle(DEV1); // Check the state of the device
if (handle != DeviceHandle.INVALID) {
// Save the device status to the record field retrieveDeviceRecord(handle);
// If not suspended, shut down
if (record.getStatus() != DEVICE_SUSPENDED) {
pauseDevice(handle); clearDeviceWorkQueue(handle); closeDevice(handle);
} else {
logger.log("Device suspended. Unable to shut down");
}
} else {
logger.log("Invalid handle for: " + DEV1.toString()); }
}
... }

Using Exceptions: 

public class DeviceController { ...
public void sendShutDown() { 
try {
tryToShutDown();
} catch (DeviceShutDownError e) {
logger.log(e); 
}
}

9. Delete Commented Code 

Comments do not make up bad code. Informative comments are always good but what about the commenting-out code? Try your best to avoid doing this.  

InputStreamResponse response = new InputStreamResponse();
response.setBody(formatter.getResultStream(), formatter.getByteCount());
// InputStream resultsStream = formatter.getResultStream();
// StreamReader reader = new StreamReader(resultsStream);
// response.setContent(reader.read(formatter.getByteCount()));

 Others who see that commented-out code won’t have the courage to delete it. They’ll think it is there for a reason, and then it gathers like dregs at the bottom of a bad bottle of wine.

10. Make the Commitment

It’s not enough to write the code well. The code has to be kept clean over time. Code degradation isn’t new, but, for some, taking an active role in preventing it might be.

The Boy Scouts of America have a simple rule that we can apply to code:

Leave the campground cleaner than you found it.

 

Related Articles

Stay-Up-To-Date

Keep in the loop with the latest in emerging technology and Mutual Mobile