Be proud of your legacy code. Extract concerns. Make exceptions from DRY. David Heinemeier Hansson’s keynote at RailsConf Europe 2008 was titled “Living with legacy software”, and centered around the notion of how to deal with your own old code. The articles summarizes the talk.
Rails has been around for 5 years now, and that’s an eternity in software, David said. People who are moving to Rails, see the platform as a salvation for their legacy applications, and as an excuse not to have to think anymore. That’s wrong, David pointed out with a big read slide.
People use the term legacy as though it is a well-defined attribute of code base, but it is really an personal opinion. “PHP is legacy! Java is legacy! - well, that one may be right”, David said jokingly, but really legacy is about your own evolvement of your taste, your knowledge and your personal preferences. Most people who wrote legacy code, thought the code was great when they wrote it. Later people’s perspective change, and even though the code hasn’t changed, it is suddenly considered legacy.
David compared code to a tomato. In the beginning you have a beautiful red tomato, but before you know it, it has turned into a rotten tomato. But it is not the software that change, it doesn’t rewrite itself. The code is not making itself worse, it is our perception that change. So why see legacy as a rotten tomato? Why can’t it be about you? You got smarter. You learned more. When that tomato got rotten, that was a process in you. That’s not something to feel sad or depressed about, that’s cause for celebration. Legacy software is not a negative thing, it’s a positive thing, as it shows that you have grown as programmer.
If you don’t accept that your code will become legacy, you will be disappointed again and again. The best programmers write the most legacy software. The more software you are writing, the more you are looking back thinking: “This feels stale and old”, the better you have become. Howver, you don’t change your perceptions as much when you have working with a platform for 5 years. The better you become, the longer you must spend on a project to learn something.
David quoted Joel Spolsky: “Good software takes 10 years to write”, but then rephrased it to: “Truly successful software takes 10 years to write”. If you want to make something successful, you are going to have work with it for a long time. “Now is the time where Basecamp is having the most impact and reaching most people, so now is the time where I should be most engaged in it”, David said. The goal for everybody should be to be involved with software that could take 10 years to write, and be happy about it.
Another Joel Spolsky quote is: “The single worst strategic mistake that any software company can make: Rewrite the code from scratch”, and I fully believe in this, David said. “Basecamp was the very first project I wrote in Ruby, along with Rails. In so many ways, Basecamp felt so legacy to me.” But you can’t solve all your legacy decisions in one big swoop, you have to do it step by step.
As a rule of thumb for cleaning up legacy code, David used: “You have to leave the code you touch in a better condition than you found it”. As an example, he showed the ApplicationHelper from Basecamp: 500 lines of different helper methods for a broad variety of purposes. The ApplicationHelper was introduced to solve the problem that helper methods, used in multiple controllers, had to be extracted into modules and included everywhere they where needed. Unfortunately this has turned ApplicationHelper into a garbage can - a broken window. Today, we can just write helper :all in our controllers, and this allows us to extract methods into separate helpers with describing names such as LayoutHelper. In fact, ApplicationHelper is supposed to be empty. It is a staging point, where you put things you don’t really know where to put. Just like you put things in lib before you put them in a plugin. But eventually, methods in ApplicationHelper should be put into separate helpers.
Then David introduced the notion of a concern. As an example, he showed the Person object of Highrise, which has a relation to configuration. This is only used for recording if the has seen a certain system notice, and is not really a core part of what defines a Person. For this reason, the code should be extraced into a concern, which is nothing more than a module with certain aspects of Person. A concern is not introduced for the purpose of reuse, but to heighten comprehension and coherence in your application.
A last point in the keynote was that exceptions from the DRY principle (Don’t Repeat Yourself) exists. It can be really hard to change just one thing a completely DRY application. As an example, David explained that Highrise has the abstract class Recording, which fits pretty well with three subclasses, but was giving him problems when a fourth subclass, quite different from the others, was introduced. This resulted in a very complicated view partial for recordings, and a more pragmatic solutions was to create a separate view for the new subclass, duplicating some code, but eliminating a lot of checks in the original partial.
Legacy ain’t so bad, David finished off, it keeps you honest about yourself and how you are growing as a programmer.
Hello, I'm Casper Fabricius. I have developed for the web for 8 years, and have been enjoying Ruby on Rails for the past 3.
My experience covers communities, shopping solutions, multi-language sites, heavy back-end lifting and a wide selection of more traditional websites. I currently favor Radiant CMS as a platform, and I am an expert Radiant extension developer.
I am based in Copenhagen, Denmark, but I take assignments from across the globe. Feel free to study my resumé, featured projects and - of course - to hire me.