rc3.org

Strong opinions, weakly held

Tag: best practices

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:

Conditionals make code expensive to test; so ceremonial conditionals are a particular nuisance. Let framework error handling deal with missing data on the form.

I need to give that one a little more thought.

My rules of thumb for developers: use less indentation

Over a month later, post number two in my “rules of thumb” for developers series. The first post was on writing less code, period. This one is on using less indentation.

What I really mean by this is that I’m strongly not in favor of complex nested code structures. I find them to be difficult to follow when reading code, and to be good places for little logic bugs to hide. How often have you seen code that looks like this?

if (something > 10) {
    if (something < 100) {
        // Do something
    }
    else if (something > 150) {
        // Do something else
    else {
        return false;
    }
}
else {
    while (something < 10) {
        // Do some other stuff
    }
}

I often see conditional structures three or four levels deep, comprising case statements, if statements, and loops of various kinds, and in those cases, it can be very difficult to figure out exactly which conditions have to be in place for a given line of code to be executed.

Let’s look at a really common sort of coding problem:

private boolean doSomeStuff(String str) {
    if (str.equals("something")) {
        // Perform some tasks.
        if (str.length() == 10) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
        return false;
    }
}

I would always write that method like this:

private boolean doSomeStuff(String str) {
    if (!str.equals("something)) {
        return false;
    }

    // Perform some tasks.

    return str.length();
}

Any time there’s a condition that causes code to be skipped, I like to put the return statement above the code that could be skipped. It enables me to avoid a level of indentation and, I think, makes the code more readable. This approach goes hand in hand with the practice I’m going to discuss next, which is to write more methods. I think it’s always better to be able to quickly figure out which code you can ignore when you’re reading through code and trying to figure out why something is happening. In the second version of the method above, it’s easy to see the conditions under which you can ignore most of the code in the method.

It’s particularly important to avoid excess nesting when you’re talking about mixing markup with code, in PHP files, JSPs, ERB templates, or whatever. Excessive nesting can render the source nearly unreadable. It’s almost always better to use includes or other approaches to make it easy to distinguish between the control structures in the page and the markup used to render the page.

This practice may seem pretty obvious, but I don’t think I’ve ever seen it explicitly describe before, and I read a lot of code that includes lots of deeply nested structures. I’d love to hear in comments whether people see any downsides to this approach, because I’m methodist when it comes to writing code this way.

My rules of thumb for developers: less code

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:

  1. Write less code.
  2. Use less indentation.
  3. Write more methods.
  4. 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

  1. 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.
  2. 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.

Use constants instead of string literals

One practice that I internalized a long time ago but that I still see a lot of experienced developers ignore is habitual . Most applications have common strings that are used in a number of places. These should pretty much always be stored in constants (however your language of choice implements them) rather than appearing as string literals anywhere other than when they are initially assigned. For example, a blog publishing tool might have a status field for posts with possible values of “published”, “draft”, and “scheduled”.

If you’re writing Java, you might write code like this:

blogPost.setStatus("published");

and

if (blogPost.getStatus().equals("published")) {

     // do stuff }

The reason this is bad practice (even though it works like a charm) is that it costs you an opportunity to let the compiler do work for you. Let’s say you write your code like this:

public static final String STATUS_PUBLISHED = "published";

blogPost.setStatus(STATUS_PUBLISHED);

if (blogPost.getStatus().equals(STATUS_PUBLISHED)) {
    // do stuff
}

If there’s a typo in that code, the compiler will catch it for me. Typos in string literals are the cause of a huge number of difficult to diagnose bugs, and are easy to avoid. There are other advantages to this approach as well, especially if you use an IDE like Eclipse. If put a string in a constant, I can use the “References” feature in Eclipse to show me every spot in my code where the constant appears. In a couple of seconds, I can discover every place in my application where the status of a blog post is set to “published”. There are all sorts of other advantages as well, like being able to rename the constant using the rename variable refactoring in the IDE as opposed to search and replace.

This practice is on my mind this week because I finally bothered to learn about Ruby constants, which are incredibly easy to declare and enable me to apply the same practice that I always use when programming in Java.

To create the same constant in Ruby, you’d just type:

STATUS_PUBLISHED = "published"

You can, of course, reference it by name, and if it’s declared in a class called BlogPost, you can reference it like this:

if status == BlogPost::STATUS_PUBLISHED
    # do stuff
end

Ruby will happily show you an error message if you reference that constant without declaring it first, so even though Ruby is looser in terms of variable declarations than Java, the compiler will still help you out in situations like this.

PHP also has constants but in my opinion the declaration syntax makes them a pain to deal with. (I still use them when I’m programming in PHP, though.)

© 2024 rc3.org

Theme by Anders NorenUp ↑