Let’s talk about frameworks, programmer edition
In the previous entries in this series I’ve been talking mostly about the benefits of the new web frameworks that have been popping up over the last year or so. And from a programmer’s perspective, there are certainly a number of benefits:
- Speed. Because a framework gives you a solid foundation of code for common functions, it also gives you a pretty big head start on a new project. Generic data modeling and object-relational mapping, coupled with solid data-access APIs give you an even stronger boost, cutting development time significantly.
- Flexibility. Frameworks operate on a generic enough level to let you tailor the applications you produce to your particular project’s needs.
- Best practices. Frameworks can give designers a gentle introduction to guidelines like clean separation of code, and they can easily do the same for programmers — the framework’s architecture will naturally guide a programmer into writing clean, modular code.
- Improved communication. This one, I think, is the big win for designers, and is also big for programmers; by getting both sides closer to understanding an entire application — both front and back ends — frameworks help designers and programmers better understand each other.
This time around, though, I’m not really going to be focusing on the benefits of web frameworks for programmers, because hopefully they’re pretty obvious to that audience — programmers wouldn’t be creating frameworks in the first place if they didn’t see the advantages.
But if you hang out in the right places, you’re likely to see a lot of programmers complaining about, rather than praising, frameworks; there are several common criticisms that come up over and over again as justification for dismissing web frameworks and their advantages. So in today’s installment I’ll be picking up some of these criticisms and doing my best to respond to them.
I can already write this sort of code. Why do I need someone else to do it for me?
At first this seems like a logical argument — if you have the skill to do a thing, then you have no need for someone else to do that thing for you. But this ignores the power of convenience; sure, you could write all your own data-modeling code and all your own database-access code and all your own dispatching code and all your own templating code. But do you want to?
Maybe you’ve met some programmers who write desktop applications. Do you ever hear them saying “I know C and how monitors and graphics cards work, so why do I need someone else to write a graphics API for me?” How many of them do you know who bypass the operating system and hardware drivers and try to control the read-write heads of the disk drives themselves?
In one sense, a good framework is like an operating system; it takes the sorts of common low-level tasks that everybody needs, and deals with them for you; then, instead of writing code to handle those tasks yourself, you call on the framework’s APIs.
Though a good framework, just like a good OS, knows that there are still times when it’s useful to get a little closer to the bare metal, or its web equivalent. Which is why all the popular ones let you bypass their object-relational mapping and database APIs and just write SQL if you’ve got a situation where that’s the most efficient thing.
I don’t trust other people to write my application for me.
In that case, I sincerely hope you’re writing in C or some other compiled language. If not, you’re already trusting someone else to write part of your application — you’re trusting the people who wrote the PHP interpreter, or the Perl interpreter, or the Java virtual machine or whatever interpreter your language of choice uses.
Of course, if you wrote your own interpreter or VM, then you may ignore this point. Also, I salute you.
And odds are that you’re not just using the core language, either; if you’re a PHP developer you’ve probably used something from PEAR. If you’re a Perl developer and you’re not using CPAN, then you’re even crazier than most Perl developers I know. Every language in common use on the web is modular to some extent, and I’ve yet to see a developer who hasn’t taken advantage of that at some point.
So it’s pretty much a given that if you write web applications you’re already trusting someone to write some of your code for you. So rather than issue blanket statements about how you don’t trust anybody, and which frankly just look silly at this point, why not treat a framework the way you’d treat any other library or set of libraries?
Frameworks provide a bunch of functions I’ll never use. I only want what I need.
Some of this is alleviated by the fact that most of the new frameworks are highly modular; if you don’t need a certain part you can leave it out. But again, this starts looking silly when we consider it in context; if you write PHP web apps, do you grab PHP’s source and strip out all the language features you’re not going to use? How many people do you know outside the embedded application world who recompile C libraries to remove everything they don’t need?
Frameworks are libraries of code which are intended to serve general-purpose use, which means that, like any general-purpose library, they’re going to include functions you don’t need. But the functions you don’t need are going to be different from the functions Bob in New York doesn’t need. And the functions Bob doesn’t need are going to be different from the functions Carol in Seattle doesn’t need.
That libraries will include more features that you’ll probably use is a constant of every type of programming. But having those features available is, for most use cases, not problem; the extra overhead of the codebase isn’t an issue (again, unless you’re doing embedded development which, if you’re a web developer, you’re probably not) and the convenience is too much to pass up.
I don’t trust code generation.
This is based more on misunderstanding than anything else, and the misunderstanding seem to be based mostly on a feature in Rails called “scaffolding”. Scaffolding is an optional feature Rails offers — yes, that’s right, you don’t have to use it — which will look at your models and generate some stub views for you that implement basic CRUD functionality. This scaffolding works much like its physical-world counterpart; it’s a temporary structure that helps you get started, and that you throw away once you’ve finished building.
So this isn’t really the sort of code generation that programmers (rightly) tend to avoid. I’ve seen Django‘s admin application criticized in much the same way, again because of misunderstanding; the Django admin app doesn’t generate any code at all.
There is one place where frameworks do generate code which is intended to be used in the final application, though: when you’ve defined your models, they almost all will output the necessary SQL statements to create the appropriate database tables. But this isn’t an absolute: you’ll be able to edit those statements before they’re executed, if they’re not to your liking, and there’s typically also a mechanism to introspect an existing database and derive model definitions from that instead of having the framework create the tables for you. So again, this isn’t the sort of code generation that good programming practice tries to avoid.
And I’m spent
I’ve been taking notes over the last month or two every time sites like Slashdot ran stories about frameworks, trying to keep track of the most common criticisms programmers were leveling at them, and I think I’ve covered all the big ones above. Sometime in the next couple days I’ll publish the fourth and probably final installment of this series: frameworks from the DBA‘s perspective.