Frameworks, Good Code and the Opposite of YAGNI

by Charles Miller on March 11, 2004

Hani has been wondering if good code is relevant?

Excluding the children amongst you, almost everyone has seen projects that have awful awful code succeed, along with projects using all the right buzzwords and cool frameworks fail. Out there in the real world, I'd be amazed if there's any correlation at all between success and anything that actually matters to a developer.

Reading this gives me one of those "Well... Duh!" moments. There are so many factors that go towards a project succeeding or failing that one of them -- any one of them -- will get lost in the statistical noise if it is singled out. We all know projects that have been based on good code and well-practiced methodology, but never seen the light of day because something else went wrong. And we all know projects that have done everything wrong, but have bludgeoned through with sheer bloody-mindedness and force of will.

The thing about writing good code is that while you might still fail with it, at least if you fail you'll know it wasn't the fault of the code1. As a programmer, you can't take responsibility for the relationship with- or demands of the customer, you can't take responsibility for changes in the economy or budget cut-backs, you can't take responsibility for the market-research that drives the project or the marketing that must sell it when you're done.

As a programmer, you're responsible for the code. If any of these other things get screwed up, your project may well be doomed. If any of these other things are done well, your project may succeed despite bad code. But at the end of the day, your job is to make the best of what you're being paid to do.

Much of Hani's wrath falls on the creation of web frameworks.

All these frameworks and web doodahs are more often than not simply the product of a hopelessly bored mind desperate to inject some sense of meaning into their daily grind. All the business asked them to do was product an app that solved a specific need. Nobody told them to go invent a framework for it, or to maximise reusability, or to componentise the moving bits, or to use TDD, or to opensource anything.

If I were to write a web application of any significant size using purely YAGNI methods: starting with a blank slate and only ever writing code that takes me towards concrete functional goals, it wouldn't be long before I started seeing that I was wasting a great deal of effort. I'd be copying and pasting a whole lot of code, and modifying the app to add new stuff would be increasingly difficult.

So I'd start refactoring the repetitive stuff into modules that I could reuse. This wouldn't be the result of a hopelessly bored mind, it'd be necessary for me to be able to work faster. I could do without it, and it probably wouldn't mean the difference between the success and failure of the project. Lots of projects have succeeded through cut-and-paste programming. But reducing the amount of code you have to write (or paste) for every function, you reduce the probability of bugs2, reduce the amount of time it takes to write the damn thing, and generally save somebody some money.

Do that enough, you'll end up with a framework.

Work on enough web application projects, and you'll get sick of working up to the framework from scratch. You know raw web applications are tedious exercises in repetition. You know you've solved this problem before. YAGNI gives way to IKIFNI (I Know I Need It)

I've recently started writing a web application in Ruby that will never see the light of day (it's purely a personal exercise to keep my brain ticking over), and the first thing I did, in accordance with IKIFNI, was to look around at the available web frameworks. Having spent the last three months working on a project based on Spring, WebWork2 and SiteMesh, the last thing I want to do is go back to plodding around doing the same things that these frameworks have helped me avoid having to do.

Unfortunately, I couldn't find one that didn't seem like the bastard child of Struts3. So I started building my own4. Because I know I'm going to need it.

1 Like all blanket statements, this isn't always true. In some death-march cases, you're best off writing really bad code really quickly, just to get something up and avert the cancellation of the project. But for the general case, it's a good rule of thumb.
2 As bad as "lines of code" are as a metric of productivity, they're still a remarkably good predictor of bugs.
3 Give a reasonably good OO developer the task of building a web framework, their first attempt will probably be something resembling Struts. Which I suppose gives good support to the "Build one to throw away" theory.
4 Which bears only superficial resemblance to any of the aforementioned, but I suppose pays homage to each.

mapper =
mapper.add_mapping(".*\.ahtml", AmritaAction5, { Mapper::ALL => :render }, {})
mapper.add_mapping("/hello", HelloWorldAction,
  { Mapper::POST => :greet, Mapper::GET => :display_form },
  { :input => "/form.ahtml", :greet => "/out.ahtml" })
mapper.bind_to_server("/", webrick)

5 Amrita is a temporary measure. It's a clever idea, but one gets the feeling nobody's ever done anything serious with it, because its limitations became painfully apparent just from writing Hello World.

Previously: Introspection is the Enemy of Blogging

Next: Google Evil?