May 16, 2008

Test Driven Development and Getting Things Done

I'm sure someone, somewhere, has already determined this.  It's probably been blogged about before, but I just realized something today.  Test driven development dovetails nicely with David Allen's time management book Getting Things Done.  By creating your tests first, with or without even marking them as TODO tests, builds you a TODO list of sorts for your project.

Other than just being a different way of doing things, I never really took to test driven development for small or personal projects.  Most of my projects are web applications and "unit testing" modules never seemed worthwhile because you weren't easily able to test the database and web interactions.  Well I can easily say that Perl Testing: A Developer's Notebook by Ian Langworth and chromatic has shown me the way.

I had always focused too much on ensuring that 'make test' would be able to be run from anywhere and simply did not think about the fact that I could automate most of the work of building a test environment and if I wasn't able, to bail on those tests so they would be skipped.  For example, you could automate creating your PostgreSQL database, but what if PostgreSQL isn't installed on the server or what about when your user isn't allowed to create databases?  You just bail out of those tests.

I was definitely too concerned with getting 100% of the tests to pass 100% of the time, in all possible scenarios now that I think about it. 

March 11, 2008

Want to be a better manager?

I've been reading a great book recently titled First, Break All the Rules: What the World's Greatest Managers Do Differently. I highly recommend it for anyone who manages employees, but it makes two great points early on that are especially appropriate for technology managers:

Treat your Employees Differently

You should treat your employees differently.  Each has unique strengths, weaknesses, and differ in the way they learn and you should capitalize on that, not try to homogenize everyone. Sally might be an awesome systems architect, so you don't want to weigh her down pounding out mundane features.  Bob might be the fastest developer and giving him those same mundane features makes sense.  Steve on the other hand might be your more efficient debugger, etc. 

They learn in different ways, some by reading, others by doing, and some need a more traditional classroom environment. Sending a do-er to a lecture class is a waste of everyone's time. 

Don't Let Human Resources Get in the Way of Your Hiring

I've touched on this topic before, but you can't leave the resume collection and filtering process to your HR department.  Even in our more tech savvy age, I still hear horror stories from programmers how they lost out on being interviewed for a job because the HR person didn't know J2EE or J2ME were 'Java', that Ubuntu is a Linux distribution, or that having 6 years of mod_perl experience probably means they know Perl pretty well.

A great technology manager has to hire a person based on several things, one of which is experience with a particular technology or technologies.  But that's only part of it.  Troubleshooting skills, breadth of experience in many technologies, personality and how this new hire will fit into the overall team structure are just as important.  The worst possible case is when the manager is barely or not at all involved in the hiring process.

Now there are exceptions to this.  The best example is my friend Josh Stomel who runs NeoHire. Josh is one of those rare recruiters that actually understands technology and more importantly knows when he doesn't know and has a huge network of geeks like me to ask questions. You can just hand NeoHire a list of qualifications and they will bring you back a group of top notch talent.

So it is possible to have HR deeply involved in the hiring process, it just has to be the right people. 

January 17, 2008

Making the software written in any language more readable

There are two very simple ways to improve the readability and maintenance of the software you write. They are so simple they are often ignored in favor of more complicated tools and the various programming methodologies people blather on about.  This comes from our human nature to think our own problems are more special and complicated than they really are and from not following the KISS principle.

So how do you improve your software?

By using better names and being consistent. It really is that simple, which is probably why it is overlooked.  A development manager might score some points with his boss by switching to Agile programming, having some scrums, doubling the amount of developer documentation or maybe even switching to a whole new platform like Ruby on Rails.  But who scores any points by saying, "We're going to do better about naming things appropriately?"

Appropriate Naming

Obviously having a variable named temp_user isn't all that descriptive, but it is an improvement over just temp or simply t. Most, if not all, programmers realize this.  However, you will often see variables named clt when they should really be named client, as if those three extra characters were single handedly going to cause carpal tunnel.  Your variable names should be as descriptive as possible without being absurd about it.  A variable named the_current_user_object_we_are_working_with is obviously overkill. But perhaps current_user_object or even current_user is appropriate.

Naming your functions and methods should also be given the same amount of care. Naming a function fix_client doesn't tell us anything useful, we can only speculate something is wrong with the client or the data and this function does something about it.  normalize_client_name is a much better name when you read that all the function does is properly set the case of the letters in the client's name.

The names you choose for your libraries are also very important.  This is one of the reasons programmers find Perl's CPAN much more useful than other programming languages' library collections. Things are named and categorized (for the most part) sanely.  Need something related to E-mail, check the libraries in the Mail category.  Can you guess what Net::SSH, IO::File::CompressOnClose, and WWW::Google::News do? Yeah I thought you could.

If I stumble upon your use of a library called Util, it doesn't tell me anything I still have to go look at the library to see how it fits in with this code.  If it had been named something like  DB::Util or Client::Utils I would at least know the library is probably related to the database or client.

Consistency

Consistency is another area where you can improve your code base without much effort.  If all of your classes contain an initialization method, they should all be named the same.  Not initialize in some classes and init in others.  Things that should be consistent throughout your code base, not only consistent within a single application. If possible, the source in your department should be consistent with other departments and business units.

Consistency through conventions is one of the main reasons people like web frameworks like Ruby on Rails. I'm not advocating Ruby on Rails necessarily, you can accomplish these same things in any language.

Things that should be consistent:

  • variable, function, and method naming conventions ( underscores or CamelCase, but not both )
  • frequency and layout of comments
  • documentation
  • configuration file syntax
  • on disk layout of source code, binaries, configuration files, etc.
  • installation, upgrades and package management
  • language(s) used for development

The point being the more consistent you are in how you build an application the easier it is to get down to the task at hand.  Be it new development or bug fixing.  Got a configuration file format you like and have already written libraries to parse it? Then use it EVERYWHERE, in every single darn application you build. No one has to learn the new format to start developing, no time is spent discussing which format is better, and another developer in your organization can jump in to fix bugs or add a new feature.

The last development shop I ran we focused on being consistent. 95% of the time we were building web applications that were either used internally by fellow employees or externally by our customers.  If you saw the source to one of our applications, then all of our other applications would seem very familiar. One might be a ticket tracking system and the other an accounting package, but the layout, coding style, and use of common libraries let the developers dive right in and not have to worry so much about how this particular app is written differently than the others.

Consistency in your applications also makes refactoring easier.  If all of your applications use a particular technique, library, etc. in the same way replacing it with a new tool you have fallen in love with is much easier.  If everyone is doing everything even slightly differently, you have to start worrying more and more how the change might impact your code.

I'm definitely a "right tool for the right job" sort of fellow, but mixing and matching tools and techniques for every single application you build is a recipe for disaster. One shop I know (name withheld to protect the guilty) has two developers.  One who works entirely in Perl, the other entirely in Ruby.  Another application I saw was written mostly in Java, but with a smattering of C# and Python around the edges for kicks. None of these three were chosen from a "right tool for the job" perspective, but simply because those were the favorite languages of the specific developers tasked with those sub-systems. These are obviously worst case examples.

These ideas aren't new, I'm positive I am not the first to use them or even write about them.  But I see these two simple rules violated so often by programmers of all experience levels that I felt the need to reiterate them.


August 30, 2007

Technique for improving code over time

I was talking with a friend of mine recently about an all too common problem in software development.  That problem is finding the time and resources to revisit working, but not perfect code.  For whatever your definition of "perfect" may be.

The developers feel this particular bit of code is just plain nasty. Maybe it is written in a confusing manner, poorly documented, or the landscape has changed so much that the entire architecture could use a rethink. The programmers may have thought up a better way, changed their style/best practices, or perhaps have just improved their skills since that code was written. But it works. It accomplishes the business goals.

Because it works, the management/marketing/sales folks are not very interested in making it better.  They would rather the programmers focus their efforts on new features, because they don't feel they can sell code quality. "Maybe next month/year/release we can do that, but right now go knock out some of these TODO list items...", is what you typically hear.

Both sides of this struggle need to realize that they both are correct and both incorrect. The developers are right in saying the code isn't perfect and could be improved.  They are also wrong, because sometimes what you have is "good enough".

The biz folks are correct in their thinking that they can't directly sell the results of the programmer's effort. They can't put it on brochure and it certainly won't get them talked about in FastCompany. But they are also wrong, because they are missing the long term impact the code quality/design will have on their future business. It is difficult for them to understand how changing, for example to a messaging oriented architecture, helps their modularity and scalability. How it might drastically reduce future development time, improve testing, etc, etc, etc.

Arguing this out could take forever. Not to mention you will have to argue each architecture change as you find/want them.

A technique I have used with great success in the past is what I have so cleverly named "Friday Afternoons".  Friday afternoons are probably the least productive part of an employee's week.  They are watching the clock in anticipation of the weekend. It happens to everyone.  Experienced sales people will tell you that it is basically impossible for them to get any real sales on Monday mornings and Friday afternoons.

As a compromise,  I suggest management give the developers free reign to make architecture, design, and code clean up changes on Friday afternoons. You may need to implement rules around this, such as the changes can't impact any deadlines, they can't create any new work for others, can't impact the product in adverse ways from the customer's perspective, all work must be done in a cleanup branch, etc.

Some of you managers out there are probably thinking, but "No way, that's 10% of our development time".  If you feel this way, you're really deluding yourself. No one is 100% productive, and I would estimate no one is even 25% productive on Friday afternoons, yourself included.

So why do this? There are several reasons:

  • Developers can cleanup the code, effectively making their workplace ( aka the code ) more enjoyable. And everyone knows that Great Code comes from Happy Coders.
  • The programmers feel their concerns are being heard. That management cares about about the quality and not just the dollar signs.
  • You eliminate the time drain of the meetings arguing about these issues.
  • The coders are self-motivated in their Friday afternoon sessions. You weren't going to get much out of them anyway, but at least there is a chance that you can reap future benefits from this work.

Maybe one of those architecture changes means that a requested new feature takes 2 days to implement rather than 2 weeks.  Or perhaps the code will run 5% faster or scale 2x as well.  Even if you just end up with better documentation and a slighly improved employee morale this is win.

If you end up using this technique for awhile, please send me an E-mail or leave a comment here.  I would love to see how this idea plays out in different environments.