I do lots and lots of development with the .NET platform, mainly because the corporations in the Cleveland area that have money to fund large projects are Microsoft shops.
I used to have a real problem with Microsoft development, back when it was all Windows 95; the tools were expensive, flaky, and unreliable. Since then, the tools have improved to an amazing degree; now I can write code that actually works consistently on more than one computer, and it’s not utterly ridiculous to run Windows on servers anymore. So there’s that.
But in just the last couple of days, I’ve gotten back into the Ruby on Rails environment. Partly, I’m jamming with my college homie Dave Stagner on his amazing Congruence product; and also, I had to update this old Perl script that I’ve been using for years to sort my incoming email.
Getting started on the latter, a Rails rewrite against an existing database, was illuminating. First of all, that Rails concept of “convention over configuration” can be a minor hassle when you have legacy data. My tables didn’t conform to the Rails standard of having a unique integer key named ID, and I wanted to fix that, and then I had to figure out how to get rake to rebuild my schema.rb file.
Beyond that, though, what I was most delighted by was the lack of pretense. Rails code generators simply work, and they solve the problem in the simplest way possible. So how does my new code find a key value in the database? It calls the find() method. How do I pull a SQL JOIN? I ask for the data and Active Record figures it out.
That may not sound like much, but I look back at most of the corporate .NET applications I’ve worked on in the past five years or so. Virtually all of them have at least three layers of code and DLLs. The way I’d pull a given record in my mail-sorting application, if I did it to modern corporate standards, would be to code a Search() method in the Data Abstraction Layer, then code a usage function in the Business Layer, and then figure that the Controller Layer would know how to use it. Under that Data Abstraction Layer would be a SQL call that–because of corporate policies–has to go through a custom stored procedure that I’d need to work on with database developers.
Even better than that? Each of those code layers has to be injectable, because in theory someone might want to replace the Data Access Layer with a different implementation, and they can’t possibly be expected to do an application rebuild that only takes 30 seconds or so. No, we have to have code that’s dispatched at runtime by an object broker.
You want to know why corporate projects take so long? That’s why.
The alternative, if you don’t want to drop it all and go with Rails, is to stop adding layers of indirection until you actually need them. It’s a lesson I really wish .NET shops would listen to.