A Day In The Lyf

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

Archive for the ‘Agile’ Category

Coding Values

I always enjoy reading Kent Beck’s books. In a way, they remind me of a poster my mom has hanging in her house: All I Really Need to Know I Learned in Kindergarten. With the frenzied pace of change in software development, it’s easy to forget about the basics. A good remedy for that is to sit down and read one of Beck’s books.

Recently, I read Implementation Patterns, and while I enjoyed Smalltalk Best Practice Patterns more, I still got something out of the book (despite being neither a Java nor a Smalltalk developer). As with XP, Beck explains his programming practices in terms of values and principles. I always appreciated that, in Extreme Programming Explained (both editions), he not only described his values, but laid out concrete practices that embodied those values. In Implementation Patterns, he takes a similar approach, claiming the three values of Communication, Simplicity, and Flexibility are what inspire his programming practices.

He describes them as listed in priority order. Where they clash, which is rare, it is better to be communicative than overly simple. And simplicity trumps flexibility. Too much terrible software is written under the presupposition that it must be flexible.

What Beck did not write about were values that run counter-productive to quality code. I tried coming up some as an exercise – those that I’ve witnessed in myself and others. I was able to come up with the following:

Ownership

I’ve worked with one developer who held on to code he had written so tightly that, even after we had instituted a code-sharing policy, it took an enormous amount of effort to loosen his grip. We’d go and refactor his code, and he’d come in after us and refactor it back. We’d add functionality to his code, and he’d come in after us and change it.

There were certain very odd aspects of his behavior:

  • His code was really bad, so it was strange that he resisted outside help so much
  • Even after we started rotating coding tasks to get people involved in parts of the code they had previously not touched, he showed little interest in actually doing any of those tasks
  • He didn’t care to hear any suggestions about how to improve the system where it involved changing “his” code, because, as he like to say, “it’s complicated.”

His behavior ultimately got him fired, but not before he had time to leave a legacy of terrible code that others now struggle to maintain. In his defense, his sense of ownership exhibited a high degree of pride and aesthetics. Unfortunately, his sense of aesthetics was also quite poor, and his refusal to allow feedback meant that it’s unlikely improved much today.

Cleverness

I’ve found myself guilty of this sin a few too many times. Cleverness often manifests itself in extraordinarily terse code, using some backdoor of the language. It’s become passé these days to show off clever Ruby code, as it once was in Perl, but overly clever solutions can be found in all languages.

A related value is Knowledge, or the verisimilitude thereof. Often I find myself (or others) eager to show off that they know obscure parts of a language and use them for some temporary benefit. Knowledge-Show-Offs are easy to spot: look for phrases like “verisimilitude thereof.”

Both Ownership and Cleverness run counter to Beck’s primary value of Communication.

Comfort

How often have you seen C code in Java? Or Java code in Ruby? We are creatures of habit, and it often takes a conscious effort to break out of your comfort zone. Too often, we hold on to old ideas because they’re comfortable ideas, and label new ideas as “passing fads,” a particularly common slur in our industry.

Why is it so hard to make unit testing mainstream? Why don’t more people pair program? Both practices remove people from their comfort zone, and require learning a new way of programming.

Note that none of these values are bad in the general sense. I’d like to feel a sense of ownership about my work, to be clever, and to feel comfortable. But values collide, and we need to understand that certain values are more applicable in certain aspects of our lives than others.

Advertisements

Written by Brandon Byars

July 14, 2008 at 7:56 am

Posted in Agile

Tagged with

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

Getting it to work is not the only goal

I’ve had the good fortune of working with some really bad developers in the past. I’m sure the content of that sentence suggests some sarcasm to you; I assure you that I mean none. At one point, I myself was one such developer and didn’t realize it. This seems to be a common pattern—bad developers don’t know that they’re bad, and quite often they think they’re really good. Evidently, the pattern isn’t restricted to software developers (see this study for example).

Working with bad developers has made me a better one by seeing the results of bad practices. One of the things I now realize, for instance, is that getting something to work isn’t the only goal when working on a task. You also have to make sure that it will keep working. If you say you’re done after whatever you’re working on appears to work, you’re only doing half of your job. And probably, the easier half.

Making sure it will keep working means different things to different people. In my view, it means making sure the code is as simple as possible and getting it under a set of automated tests so that future developers aren’t afraid to change it. Too often I’ve seen bad developers point the finger at someone who has the gall to change “their” code when the change doesn’t work. “It’s complicated,” being one of the most immature and insulting complaints, as if it’s ok to erect a solid barrier around code you’ve written because you’re the only one smart enough to understand it. In my experience, that attitude represents a lack of aesthetics when it comes to coding. It’s the result of saying you’re done when you get it to work, not when it’s simple. Simple Ain’t Easy. It’s the result of thinking that testing is something that only those who aren’t smart enough to be developers do.

The desire to stop when you get something working isn’t a problem that only bad developers have; it’s just highlighted more against a backdrop of bad developers. But it’s a discipline that even good developers break from time to time.

The team I’m currently working with is easily the most competent group of developers I’ve ever worked with. We’re actually pretty decent at trying to keep things simple and get as much of our code tested as we know how. But there’s some code which we just haven’t found good ways to easily test yet. And unfortunately, we still break code changing it.

In my opinion, being afraid to change the code isn’t the answer. In fact, being afraid to change the code seems like the worst possible solution. It’s surrendering. It’s giving up on the aesthetics that make coding fun and fulfilling.

We’re still working on a solution. My idea for the moment is to use the bugs that do get through as opportunities to improve our integration tests. We use Watir, for example to test the web site, and the controller and view code in the web site has proven too difficult to effectively unit test. I think a good mindset is to extend the lesson learned about not stopping when you get something to work to bug fixing. If a bug does get through, don’t say it’s fixed until you see a failing integration test that exposes the bug, and then see the test pass after you’ve made the fix. The fix itself then becomes, in many cases, the easiest part of bug fixing.

It’s funny how many developers think that’s overkill. I remember, way back when when I first saw the traditional waterfall model, seeing something like this:

Requirements – Design – Code – Test – Deploy

It doesn’t matter whether you’re doing waterfall or a more iterative cycle. Coding, while obviously important, doesn’t dominate that cycle. Too many developers act as if its the only part of development.

Written by Brandon Byars

June 12, 2007 at 10:44 pm

Posted in Agile