27th Mar 2008 by Mark Turansky
“Don’t Make Me Think” applies to your code, too
Don’t make me think. That’s how I feel about your code.
Or as Martin Fowler puts it:
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” -Martin Fowler, Refactoring: Improving the Design of Existing Code
You’ve reached a whole new level of mastery when you write for simplicity, elegance, and maintainability. This is done on purpose, and it’s hard to get right. Deadlines, schedules, pressure, and stress all encourage us to cut corners and adopt a “Git ‘er done!” mentality. But Abandonment of planning under pressure is one of software’s classic mistakes. It’s a cardinal sin.
How do you write simple and maintainable code? I’ve got a 3-step program for you:
Step 1: Admit that simple isn’t easy
Designing simple software is hard. It has to be done on purpose. You can’t accidentally find yourself with well-written code and an elegant solution, it has to be written that way on purpose.
This admission is a bedrock principle required for designing great software and products. If you can’t admit that simple is Hard Work™, you haven’t hit rock bottom yet by having to maintain code that would make readers of The Daily WTF blush.
Step 2: Read “Don’t Make Me Think”
Steve Krug’s excellent book “Don’t Make Me Think” is about website usability, yet it changed how I look at my code.
Why? Because Steve applied the same principles in his book to his book! And if it works in those two mediums, I thought it just might work for me, too, in my medium (code).
“Don’t Make Me Think” is very easily absorbed because he’s feeding you information in a readily accessible way. He wrote it simply on purpose, and I’m certain it took many more hours to edit than it did to write. Simple is hard.
Step 3: Practice simple everyday
There are innumerable decisions you make everyday that affect your project for better or worse. You need to recognize these as the opportunities they are. Here are a few things you can do every day:
dao.findCustomerBy(order);
Or what about this if statement?
if(admin.hasPermission(Permissions.VIEWFILE)){
// allow...
}
or better yet…
if(admin.hasViewFilePermission()){
// allow...
}
The pretty method on the Admin class looks like this:
public boolean hasViewFilePermission(){
return hasPermission(Permissions.VIEWFILE);
}
Date dt = march(28, 1973);
When I’m reading through unit tests, I’d much rather see the above statement to create a date than the equivalent Java:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, Calendar.MARCH);
cal.set(Calendar.DATE, 28);
cal.set(Calendar.YEAR, 1973);
Date dt = cal.getTime();
You can find those convenient date methods here: dates.java (it’s Free software). Use Java 5’s static imports to make the short date seen above.
That’s it. Three steps to better code. Putting it into practice won’t be easy, but if you want to be a master of your craft you’ll embrace the challenge and write things simply on purpose. The people who follow you and maintain your code will appreciate it.
What's next?
Leave a comment
Digg it
Save This Page
Filed under 


Never nest ternary statements
Disagree. Ternary statements get a bad rap, and IMO the reason is because people don’t format them properly. When you write them like this, they’ actually quite readable.
String successStr =
step1Succeeded
? “success”
: step2Succeeded
? “success”
: “fail”;
or
String successStr = step1Succeeded ? “success” :
step2Succeeded ? “success” :
“fail”;
Great. My formatting got stripped.
Look here if you want to see the formatting I’m talking about:
http://darose.net/NestedTernaryFormatting.html
String successStr = step1Succeeded ? “success” :
step2Succeeded ? “success” :
“fail”;
breaks the other rule: “Don’t make me think”…. i.e. if you think what it means you’ll get it, but you won’t get it without thinking.
DAR
Agree with Mark and Dimitre. Too much thinking required to figure out what the hell is going on in nested ternary statements. You’re trying to be too clever for your own good, and I guarantee you something will go wrong with your code down the line. And probably not because you broke it. But because someone else didn’t understand what your statement is doing. Computers are fast. Don’t worry about optimizing a few lines of code for the computer - optimize for the human reading it.
Generally I’d say you really missed the whole point of Mark’s post. It’s not about making the computer do the right thing. That’s easy. The hard part is helping humans understand what is happening. Nested ternary statements fail the latter. ALWAYS.
In fact, to add to Mark’s general rule of thumb - I will just go ahead and say never nest statements more than one level deep. You’ve done something wrong if you need that level of complexity. Break it down. Simplify it - and write for the junior level coder that will be maintaining your code after you are long gone sipping margaritas on the beach.