I was discussing basic coding philosophy today and realized that I have a few rules of thumb that I bring to my programming. I guess you’d call them a basic sensibility of how to write code. The four big rules are:
- Write less code.
- Use less indentation.
- Write more methods.
- Externalize everything.
I’ll write separate posts for each of these rules, starting with this one.
The “less code” movement has gained a lot of attention over the years, mainly with people migrating to scripting languages (like Ruby and Python) from Java. Using languages that encourage concise coding is helpful, but you can adopt less code as a philosophy regardless of the language you use.
Why less code? When I talk about my work as a programmer, I put it in two categories–problem solving and typing. I want to spend as little time as possible on the typing so that I can spend more time on the interesting stuff. Nothing agitates me more than starting a new project that’s going to require lots and lots of typing with very little problem solving. I consider less code to be an absolute good in this regard. Less code means less typing.
The second reason for “less code” is that it means there’s less code to maintain. I spend a pretty fair percentage of my time explaining why code works the way it does to other people. The more code I have to slog through to answer questions, the more time I spend on the answering. The ideal application would consist of nothing but clear, simple business logic. Declarations, error handling, database infrastructure, logging statements, and network code are required to make the computer work correctly, but in most applications they tend not to be very interesting. Less code of this type is always good. If you can make your application better by spending time on this stuff, do so, but usually there’s no reason to write it and maintain it yourself.
Here are some general approaches that can enable you to avoid writing code you don’t need.
Use Economical Code Constructs
The first is to use the most concise language constructs you can. For example, you can take Java code that looks like this:
Iterator it = someCollection.iterator();
while (it.hasNext()) {
String foo = (String)it.next();
}
into a block like this:
for (Iterator<String> it = someCollection.iterator(); it.hasNext();) {
String foo = it.next();
}
That saves you a line of code and a bit of pollution in your local namespace. If you’re using Java 5 you can write even less code:
for (String foo : someCollection) {
// Do stuff
}
Using the enhanced “for” loop saves you lines of code and leaves you with less namespace pollution and more readable code. This example isn’t very exciting, but it’s the sort of economizing you ought to be doing.
Avoid Redundancy
A second and more important way to write less code is to avoid redundancy. What I mean here is that if you’re using copy and paste when you’re editing code, there’s a very good chance that you’re doing something wrong. It’s almost always the case that rather than copy and pasting, you should be creating a new method and calling it from both places. Two classes that are mostly the same should probably extend the same base class. In cases where subclassing is not the right answer, you should be using composition to share functionality among classes rather than duplicating code.
Obviously code duplication means you have more code, but it also makes your applications much more likely to contain hard to find bugs. When those two methods that do the same thing get out of sync, problems are almost certain to ensue. It’s funny that DBAs understand this incredibly well but many programmers do not. The entire point of database normalization is to avoid storing the same piece of information in more than one place. Programmers should adopt this philosophy as well.
As an example, one of the danger areas for code repetition is in input validation. Redundancy often occurs because validation code is written in two different languages–JavaScript and whatever is used for back end code. I oftentimes find the same redundancy within back end code. The Web layer has one implementation of validation, and there’s also lower level validation that takes place in the business layer. “What describes a valid instance of this object?” is a question that, ideally, will only be answered once.
Pick Your Libraries Wisely
It’s perfectly reasonable to choose libraries in part based on how little code they force you to write. One compelling reason to use Spring (a Java dependency injection library) is that it enables you to avoid writing lots of code that does nothing more than wire your objects together. One of the most compelling advantages of jQuery among JavaScript libraries is that lets you get a whole lot done in a very small amount of code.
This is also the primary advantage of persistence frameworks like Hibernate. They eliminate the need to write code to manage database connections, construct prepared statements and do all of the other database-related chores that lead to more code in an application.
Enabling you to do more with less isn’t the only reason to pick a library, but it’s a big reason to choose one library over another.
Some Other Tips
- If you use version control, quit commenting stuff out, instead just delete it. I’m talking about that method you commented out six months ago. Get rid of it. You have a copy in version control and it’s just taking up space.
- If you’re a Java programmer, your IDE will probably warn you if you have a variable or a method that’s not referenced by anything. Either that’s a bug or there’s some code you can get rid of.
There’s a whole additional article to be written on this same topic about JavaScript, CSS, and HTML and how you can use them together to produce less code. I’m not sure I’m the best person to write it, though.
Skipping the error handling?
The Relevance blog has an excellent post on simplifying code called Refactoring from Ceremony to Essence. In part it explains why people find Ruby on Rails to be a compelling alternative to J2EE, but it also illustrates a number of techniques applied by Ruby on Rails that could just as easily be used regardless of which language you’re using to develop your applications.
One point in their post directly addresses the “use less indentation” rule I posted about on Sunday. I spoke in favor of doing all of the basic sanity checks up front in a method and avoiding nesting, this post recommends leaving them out entirely:
I need to give that one a little more thought.