Sunday, January 28, 2007

Psychology of Extreme Programming

Converts rabidly follow Extreme Programming not because it is a good design/development methodology (though it has some good idea), but because it is good to developers. XP's methodologies cater to the fact that software engineers are people with foibles and attention spans, just like everyone else. Each of the tenets of XP help keep people motivated, which is key to producing a good product.

Pair Programming

Developers' lives are filled with distractions. When Joe Developer wants a break from programming he is already on a computer with easy access to his email, the news, or his favorite blog. When he is paired with Jane Programmer they both have a reason to keep working. Joe doesn't want to check his email for the 17th time in the past hour while in front of a coworker. Instead he stays interested in his work because the comradeship of the pair satisfies his need for human interaction that email, etc. was acting as a proxy for.

Short iterations

By developing in iterations, John D. and Jane P. always have a concrete near term goal that matters. On traditional long term projects there is an interminable period, between the excitement of the start of the project and the concreteness of shipping at the end, where ennui can set in. By breaking the project up there is always an immediate goal that they can focus on.

Unit Tests

Besides the obvious result of testing the code and hopefully producing a higher quality product, unit tests provide immediate feedback. Just as file transfer indicators, like the silly flying paper on Windows, keep users aware that something is happening, unit tests provide evidence that the program is still growing. Every time Jane P. runs unit tests she gets a sense of gratification that something is happening, even if it is just another bug to fix.

You Ain't Gonna Need It

This principle helps in two ways. First, it reins in the tendency to be an architect astronaut. Second, it keeps Joe D. from being overwhelmed. When Joe starts thinking about how the Tove is going to need to work in the Wabe and that the Borogoves will need to be Mimsy, he gets paralyzed by the daunting complexity and does nothing. However, when he applies the "You Ain't Gonna Need It" principle - o frabjous day - he is able to write beautiful code which later, when he really understands how to make the Tove Slithy, he can.

Final Thoughts

I could go on, but I have already gotten silly enough for one post. The fact is good software is written by good people doing good work. Any methodology that keeps Joe D. and Jane P. motivated and on task will likely be successful.

Sunday, January 21, 2007

Inheritance for Reuse

I am a big believer in reuse as a way to improve software engineering (and please ignore my penchant for rolling my own solution to problems because existing ones don't satisfy me). The reason that cars are relatively affordable and reliable is that the same robots that built your car also built millions of others. So once you have created the factory that builds the Ford Pinto, you can cheaply churn out millions of them and have some confidence that they will behave like the first.
The power of inheritance is that it provides a well defined way to program against abstractions. When you program against abstractions, you decouple your code from its context. Code that can be decoupled from its context can be reused. Reuse is the key to multiplying productivity.

Fixed Library

Software reuse has been around almost as long as software. A classic example is printf. Almost all of structured programming is about writing code that can be used and reused by at least other sections of the same program, if not by other programs. So reuse in and of itself is not novel. However, there are limitations to this type of reuse. In many cases you may want to do almost the same thing as the given library call but slightly differently (fprintf vs. printf). The challenge in writing reusable code is to write code that can support these differences without you having to know them up front, and without the user of the code having to actually edit it themselves.

Runtime Chosen Library

Sometimes when you are writing code you know what you want to do, but not how. When I took driver's ed they didn't know if I was going to be driving a Pinto or a Chevy Nova, but they were able to teach me to drive anyway. A standard example of this in Java is JDBC. You program against the common interfaces from JDBC and at runtime you load an implementation which inherits from this interface. Now you have the ability to replace the JDBC library you are using with little to no coding changes.

Parametrized Libraries

The most complicated, but potentially most powerful, type of library is the type that is configured by the calling program. Imagine you want to use your Pinto assembly line to make Mustangs. It would be efficient if you could just reuse the assembly line, but pass it the robots which are configured to make the Mustang instead. A common Java example of this is the Arrays.sort method. If you want to sort an array of Objects in a non-standard way you can just write a class which implements a Comparator and then take advantage of the built in sort. The Comparator is probably simpler to write and easier to test than your own sorting algorithm, especially if it has been a while since CS102. By using this inheritance the sort method gets to be reused in contexts that the original author knew nothing about.

How Not to Use Inheritance

A common thought among people first learning inheritance is that it is useful for reuse because it lets you get the functionality of the base class in the derived class. I know I thought this at first, and as a result wrote some horrendous code. In general when this is done, it is probably better to aggregate the base class rather than inherit.

Inheritance is Just a Tool

Inheritance is a tool in our software engineering arsenal. It is important to use it wisely, because like any powerful tool it has the ability to reek havoc. When misused inheritance hierarchies can obfuscate code and make it next to impossible to understand what is happening. However, when used well it can simplify code both now and, more importantly, in future maintenance.

Sunday, January 14, 2007

Configuration Files and Revision Control

Do you check your configuration files into your revision control system? What is the standard practice for this? This problem keeps cropping up for me and I have tried different solutions. I don't particularly like any of them, so I thought I would throw this out and hope you tell me how you deal with this situation.

Currently I am using Ruby on Rails for a Data Analysis project. Rails has a standard directory structure which you are supposed to follow. This includes support for separate development and production databases. It seems like what I want to do is check in this entire directory structure and then have one checkout for each developer working on the project and another checkout for the production release.

Here are my problems with this. First, it feels wrong to check passwords into revision control. This just doesn't feel very secure. Second, configuration information can change without the project changing. Mary is using database A for her developing and I am using database B for my developing. If every time Mary does an update she gets my database configurations along with my code changes, either she'll be annoyed because she has to update her config file, or I will be because she didn't and she changes my instance of the database unexpectedly.

Don't check in config filesSo the obvious thing to do is to not check in the configuration files, but there are problems with this too. When Sue gets added to Mary's and my project, she can't just check out the repository and be up and running. She needs to create all of the config files that are missing. I guess this can be part of the same documentation that includes where the repository lives, but this still seems inelegant to me. A bigger issue is deployment. When DataAnalysis version 2.1 is deployed and on Saturday night the server running it has a disk crash it would be great if Dave, who's on call and not involved with the project, could restore DataAnalysis without having to call a developer (particularly me). We, of course, have tagged the project in subversion and there is documentation telling Dave how and where to check out the tagged version, but what about the config file? If he has to actually edit a config file of an inhouse developed application, he may be tempted to call me up just to make sure it is done right. It's bad enough Dave's Saturday night was disrupted, why should mine be? How can we make deployment one step? (Rule 2 of Joel's 12 steps)

OK, so I've rambled long enough. How do you deal with this scenario? Please leave a comment and let me know, I'd love to hear it.

Thursday, January 11, 2007

Blogging Schedule

New technical posts every Monday morning
Talking to people about my blog I have gotten some suggestions. They have ranged from advising me to include what I had for lunch on my blog to the idea of having a regular posting schedule. While people seem to be fascinated by what I eat, or rather by what I don't eat, I don't think my dining habits will become a regular part of my postings. On the other hand, a regular posting schedule seems like a great idea for trying to keep readership, as people will know when to visit my blog and can expect new content.

To that end, I propose the following schedule. I will attempt to post a new technical article every Sunday evening or Monday morning to start out the week. If I have other things to say (like this message), I will post them when the mood strikes me. So if you check out this site once a week, you should be guaranteed of seeing new content every time you visit.

And yes, I am playing around with things that I can do to avoid the "walls of text" that I previously mentioned. Please bear with my experimentation.

Wednesday, January 3, 2007

Writing to be Read

Have you ever had the experience where a user/boss/coworker asks, "How do you do X?" and you answer, "It's explained in that document I sent you." and are met with, "Oh, I haven't read that yet" or "I just skimmed that". While it gives us great stories about the incompetence of our users/bosses/coworkers, it is frustrating and not productive. Here are some thoughts I try to keep in mind when writing to reduce these occurrences:

Just as the best diet is the one you stick with, the best style of writing is the one that is read. Therefore, except for reference material, when choosing between readability and completeness, choose readability. Most of our writing should probably look like we are writing for the web.

So what are other keys to making writing readable? What should I be doing to make my blog more readable?