Myopic Software Development
Myopia: the inability to see distant objects as clearly as near objects. PreferredConsumer.com
What makes a good statement? In my experience, a good statement is one that people will disagree with frequently. One of the internal quality auditors at my company has an excellent plaque in her office: “If you and I agreed all the time, one of us would be superfluous”. So, in the spirit of disharmony: Agile development is all about being myopic, that is, short-sighted.
One of the things that has always impressed me with people preaching waterfall, RUP, or traditional CMMI is how skilled they are at looking into the future. For me, this has never worked out well. I keep writing down requirements for projects that never happen, design my systems for requirements that turn out to be canned in the end, and coding my designings in a generic way, just to find out that the generic way I have designed the system, is different from the genericity that I really needed. sigh. I need a better crystal ball.
Barring huge advances in the crystal ball industry, I suspect that most people are in the same boat as me. When we try and predict the future, it is more about speculation than about foresight. The Standish Group’s CHAOS Report indicates that 64 % of the functionality developed is rarely or never used. And as often as not, the speculation doesn’t only cost, it actively hurts us. Code that we were not required to write is poorly tested and contains bugs. I am willing to bet that with any system out there, the majority of bugs are in error handling logic. Why? Because programmers think about all kinds of smart things to do with error handling, but forget to test it. When I write code, I always have pretty good unit test coverage - except in error handling blocks. Design by speculation is not just a waste of effort, it actually degrades the quality of your system.
So, what is the alternative? Until someone gives me a better crystal ball, I have to realize that I am myopic: I am unable “to see distant objects as clearly as near objects”. How can I make the best out of the situation? By focusing on the “near objects” that I am able to see reasonably clearly:
- Instead of focusing on the totality of the requirements, try to focus on what needs to be done the next 30 days or so.
- Instead of designing a generic solution, implement unit tests and continuous integration to make it easier to change your designs safely.
- Instead of designing with future requirements in hand, keep your design as simple as possible while solving the current requirements. This will make change easier.
- Instead of creating an elegant solution, use simple techniques that reduce complexity: Don’t Repeat Yourself. Tell, Don’t Ask. Write code that expresses you intent.
- Instead of trying to design the perfect system up front, refactor your code to solve the increasing body of existing functionality better.
So, is that all there is to it, then? What about Vision? What about long term planning? What about … Architecture (“you’re supposed to be a goddam architect, aren’t you?”)? Well, that’s a topic for a later post. For now: Remember that your long term vision is going to be blurry. It will probably change as it gets to be less long term. As long as we keep this in mind when we consider how much effort to spend on the long term vision, we’re in pretty good shape.
Comments:
Sergio Bossa - Jul 16, 2006
Hi Johannes,
I agree with you in many points: yes, we surely tend to look too much toward what will happen in the future. I just disagree when you say that instead of creating elegant solutions we should keep everything simple; yes, everything should be kept as simple as possible, but this doesn’t exclude good, elegant and reusable solutions: there should be some kind of middle ground.
Moreover, I think that up front development and testing of the domain model, in isolation with other layers, helps in focusing to current, real, requirements, because coding the domain model is all about solving your real problems.
My 2 euro cents.
Cheers,
Sergio B.
Johannes Brodwall - Jul 16, 2006
Hi Sergio, Thank you for you comment
I agree. “Elegant” is not a good word for what I wanted to express. Maybe “perfect” would be better. When it comes to creating reusable solutions, I try and avoid creating reusable solutions “up front”, and instead evolve them in a more myopic fashion.
When it comes to domain models, I think our experience is different. I create a skeletal domain model early, then I usually let the rest evolve as I need it. I think both approaches can be valid. Of course, before putting code into production, I like to check what freedom of motion I have left with the database schema.
~Johannes