A Day In The Lyf

…the lyf so short, the craft so longe to lerne

Archive for September 2007

On Being Dispensable

A question I like to give when interviewing prospective developers is, “what separates good software developers from bad ones?” I’ve heard different answers, ranging from “passion” to “experience.” I actually consider “experience” to be a pretty poor answer, as experience seems to correlate pretty weakly with skill.

I’ve worked with many bad developers, and I’ve been a bad developer. When I started out, I was just another Mort itching for the next Big Thing from Redmond. However, the one quality I did pick up very early was a sense of modesty about development. In my first job, I said “it’s impossible”—once. Thirty seconds later, I was shown that “it” was, in fact, not impossible, and oh, by the way, here’s how you do it. I haven’t said anything in software development is impossible since; it’s just that some things are harder than others.

I also make a habit of not saying “that makes no sense” when troubleshooting, as I’ve found out all too often that it really does make sense, once you change your way of thinking about the problem. “I don’t understand” is a much more accurate way of describing such problems. Ron Jeffries occasionally quotes Mary Doria Russell in his email signatures, and while I don’t know who Mary Doria Russell is, I certainly agree with her observation: Wisdom begins when we discover the difference between
“That makes no sense” and “I don’t understand.”

But by itself, modesty does not a good developer make. And I can’t look back over my career and say that, the better I’ve gotten, the more modest I’ve become. I’ve been thinking about that quite a bit lately—what can I correlate to skill in my own development?

Dispensability

It was thinking about that question that reminded me of a quote by Jerry Weinburg in a book I read a few years back: “If a programmer is indispensable, get rid of him as quickly as possible.”

No better quote represents the distinction I’ve seen between the good programmers I’ve worked with and the bad ones. Simply put, the bad ones all seem absolutely indispensable. And the more skilled I have become, the more dispensable I have become. A few years ago, I was considered indispensable by my supervisor and peers. Now, I’m interviewing with other companies, and my company and I are considering the ramifications of me leaving soon. What we’re realizing is that the IT department should be fine without me.

Correlating dispensability with skill will likely come across as paradoxical (or just plain wrong) to people who don’t develop software, and to people who do develop software but aren’t very good at it. I say this because, when I first read the aforementioned Weinburg book, I thought it paradoxical, and wrong. After all, I was indispensable. That I also wasn’t any good didn’t occur to me until later.

No, any good developer is a dispensable developer. “That makes no sense,” you ask? Of course it does. What makes a developer dispensable?

Dispensable developers write simple, easy-to-read code. The code is cohesive and reads based on its intent. Bad developers write code that belies the fact that the only thing their interested in is getting something to work. The code therefore lacks cohesion and is a procedural ball of mud as the use case gets more and more involved. Bad code is written from the standpoint of “how can I make the computer do this?” Good code is written from the standpoint of “how can I make this understandable to a person?” It should be no surprise that, were the bad programmer to leave, nobody else would know what the hell to do with their code, whereas when a good programmer leaves, anybody should be able to maintain their code.

Good developers write tests for their code. Not the kind of tests that are written down as a series of steps in an Excel spreadsheet (“open the Doodle form, enter ‘blurf’ in the textbox, click the ‘Snarf’ button, and make sure that 2 appears in the status bar). The kind of tests where, at the press of a button, you can find out whether your changes have broken anything. Automated tests, and for those good developers who are test-infected, there will be no shortage of automated tests to help you out when the good developer leaves.

Good developers get bored doing the same tasks over and over, so they automate them. We have some code we purchased from a vendor. It is not good code. It’s terrible to read, has no tests, and we still can’t really figure out how to deploy it. On the other hand, our code has automated builds and automated deployments. We have automated database creations and automated database migrations. We’re developers, and good developers don’t like doing things that the computer can do better. That makes it much nicer when good developers leave.

Good developers make sure that other people understand their code. At my current job, in the dark days of A Few Years Ago, we all “owned” pieces of the system and worked in separate offices with little communication. Predictably, the system sucked, but we could console ourselves that it sucked because the other person sucked, and besides, we all had nice big offices and felt important. When I became manager, I started introducing the idea of collective code ownership. Then we started meeting face-to-face each day for stand-up meetings to decide who was to do what. Then we started pair programming. Then we gave up our offices and moved into a shared war room environment to do all of our work. With one exception, our developers took the changes well. That one exception was our worst developer, and he’d do anything he could to keep people out of code he had written. He’s been gone for a while now, and we still have trouble working with “his” code. In many cases, we’re seeing it for the first time. The code sucks, it’s untested, and he made sure that nobody else ever understood it.

Another developer moved on last year, but he did everything he could to make sure we knew how to handle what he had worked on. He paired with others often and worked well with the team. Before he left, he gave a presentation with a projector on everything he could think of that we might need to know. While I hated to lose him much more than I hated to lose the bad developer, I have to admit that it’s been much easier to live without him than it has been to live without the bad developer.

Nowadays, we have a very good team. We all work together well, and everybody gets to see everybody’s code. We model our environment on XP, and it’s somewhat enlightening to reflect how XP tends to make team members dispensable over time. Frequent releases? Gotta have automation. Pair programming and collective code ownership? Gotta let others see your code. Simplicity and shared standards? Gotta make sure others can read what you’ve written. Test-driven development and customer tests? Gotta make sure others know if they’ve broken code you’ve written without having to read it.

Good developers are hard to find. But it’s much easier to lose a good developer than it is to lose a bad developer.

Written by Brandon Byars

September 16, 2007 at 7:25 pm

Posted in Agile

log4net Connection String Blues

We use log4net as our production logger, which has proven to be tremendously flexible. However, one problem I ran into was configuring the AdoNetAppender that logs to the database. It expects the connection string to be defined in the configuration file, which I didn’t want to do since it was already defined in our NHibernate config file.

This proved to be a relatively easy fix (found here):

private void  SetConnectionStrings()
{
    Hierarchy hierarchy = LogManager.GetRepository() as Hierarchy;
    if (hierarchy == null)
        return;

    using (UnitOfWork unitOfWork = new UnitOfWork())
    {
        foreach (IAppender appender in hierarchy.GetAppenders())
        {
            AdoNetAppender dbAppender = appender as AdoNetAppender;
            if (dbAppender != null)
            {
                dbAppender.ConnectionString = unitOfWork.ConnectionString;
                dbAppender.ActivateOptions();
            }
        }
    }
}

However, the problem is that log4net whined to standard error about not having the connection string defined. The result was that any console application had its output garbled (including our tests, since some of them used the production logger).

The solution turned out to be going ahead and putting a connection string in the config file, but making it obviously invalid (e.g., “<ignore>”). Then, when the logger is configured, temporarily redirect standard error:

public void ConfigureLogger()
{
    FileInfo file = new FileInfo(ConfigUtils.GetFilePath(“log4net.config”));
    TextWriter stdErr = Console.Error;
    Console.SetError(new StreamWriter(new MemoryStream()));
    XmlConfigurator.ConfigureAndWatch(file);
    ServiceRegistry.Logger = new Log4NetLogger();
    Console.SetError(stdErr);
}

Voila.

Written by Brandon Byars

September 9, 2007 at 10:01 pm

Posted in .NET

Tagged with

Follow

Get every new post delivered to your Inbox.