I've been working on a lot of different stuff lately, but one of my bigger projects is a heavily customized Drupal implementation. I've been impressed with Drupal, despite its headache-inducing global function style. In the end, I've had to do a fair amount of custom development to make Drupal behave the way I want it to. Its search capabilities and customization options are pitiful. Its ACL features are coarse. Its callback APIs are confusing at best. But it would have been a lot more work to build from scratch, and we almost certainly would have cut all of the administrative features by the time we launched.
So despite my legion of complaints, I kind of like Drupal and I wouldn't mind building a few more sites using it. In fact, I think that most of the sites that companies are developing these days should be thought of like Drupal instances: the administrative requirements are satisfied with web-based application features. The fact is that web publishing is the essence of business these days. By this I mean web publishing to encompass everything from marketing brochure sites (where different administrative users from different groups can each publish their content without squabbling about who gets to be "above the fold") to product catalogs wired directly to e-commerce completion, the administrative side of which is, in turn, expressed as a web app.
But I am embarking on a new project where Drupal isn't really appropriate, so I can use whatever language and framework I want. I looked closely at Rails and then Cake, but I realized something when I did this investigation: I don't like the principles upon which these frameworks are predicated. I don't like ActiveRecord. I don't even like MVC!
I am so damn sick of those three letters and the righteous indignation that accompanies them. People gloss "model-view-controller" as the word of the Lord, as if it were a priori fact rather than a developer workflow brought to us by the brilliant minds at Sun. The main supposed benefit of MVC is "separation of concerns." Now separation of concerns is generally a good programming practice, but MVC is only one way to achieve it, and it only provides a certain kind of separation. Sure, MVC helps keep the business logic separate from the presentation, but you can do that with a couple of well-named methods. MVC is heavily oriented around control; this means that the basic building block of an MVC application is an action. Of course, actions can be anything (including, say, "show my account page") but they are generally not composeable in any systematic way. They represent application features rather than semantically meaningful end-user elements. So to continue the example: if my account page shows my order history, my profile information, and my friends, I have a few unappealing options when I go to implement this in an MVC framework. Assuming that I already have a nice MVC triad to show each of these things independently, what do I do to roll them up into an aggregate view?
Well we can reuse the models and maybe the controllers, so we'll just need to write a custom view that shows each thing properly in this shared context. MVC votaries cheer and light yourselves on fire! Devilish concerns separated! Holy reuse attained!
But wait a second: we get to reuse the model and the controller, but what about the view code? Why does everyone just copy around view code like it's no big thing, despite DRY and all that? In an AJAX app, the view code is potentially some of the most complex and error prone stuff in the system. If we find an HTML validation error or browser bug, we're off to search our code for all the niches where we've replicated that error. Now start adding requirements like: one embedded view functions as a picker whose selection affects what is displayed in another, and all of a sudden our view is its own mini-app which is hard to reuse in any another context, precisely because our MVC framework focuses precisely on separating the view from the real object that underlies it. ActiveRecord compounds these problems by making most actions modal. This is why you have to go through and click delete on each item in a list, rather than just select them all and drag them to the trash. I don't care that there's a nifty AJAX animation for each one — it's still a Web 1.0 pattern.
It's interesting to compare Basecamp and other RoR apps to Drupal. Basecamp generally shows a big list in the middle, with actions the user can take on the right. Drupal usually shows a bazillion different modular blocks, each representing a bit of vertical functionality. Now most Drupal sites are too visually complex and use too many blocks, but in general, I think that modules better capture the ways in which the pieces of a system interact, especially when there is rich integration like drag/drop among those pieces. It's the difference between the command line and windows. When you think about it, it's kind of funny: the RoR guys have used savvy marketing to turn a weakness of their system (it's strictly modal and suports very simple view structures) into this "keep it simple and css-outlined" way of life.
I mentioned Sun earlier, and I have to take a moment to pile on. The unimpeachable goodness of MVC is usually justified by the unimpeachable goodness of Smalltalk, which, like Lisp, is one of the Technologies That is Too Awesome To Be Useful. But the fact is that MVC in its present form really derives from Sun's original implementation of Struts and what they called Model 2. You can make a pretty good argument that this is completely different from what the original model-view controller paper was about.
I mentioned earlier that I've been working on a bunch of stuff, and some of that stuff has been jumping in on a couple of enterprise Java apps. Both of these happen to use struts, and I've had a realization as I copy tile definition blocks among my config files and code from one JSP to another: the main purpose of Struts and its successors is certainly not to improve the quality of the user interface. It's not even necessarily to aid developer productivity. It's all about developer workflow. The DBA deals with the models. The Java Archit$$$ draws diagrams and worries about fancy problems like "concurrency." And the subliterate "web developers" copy around giant table definitions and debug their pages by guessing at where to put the quotes. In fact, I think you can draw a straight line from Model 2 frameworks to the rise of outsourcing: both promise that you can ship off the repetitive work of creating 250 separate pages to convey your relatively simple application features. But this misses the point: computers are good at repetitive stuff. That's what they're for.
I suppose you can argue that this approach has worked pretty well. It's certainly the dominant mode of application development within the enterprise. The funny thing to me is that the Web 2.0 kids have inadvertently swallowed the Sun enterprise development pablum and lofted it into what equates to fashion among the geek set. There's just no reason for this. The proliferation of category killer Web 2.0 apps that have the same feature set (calendars! content management! tagging!) is a direct reflection of the limitations not only of these technologies, but of this way of thinking. Sure, it's relatively easy to build these apps, but they don't do a whole lot. A meta-app that makes these applications should be able to come in and wipe out the whole category.
Drupal wants to be that meta-app, but for now at least, its lack of OOP makes it too hard to meaningfully extend or integrate its modules. Still, if there's one part of it that's successful, it is that its organizing principle is a component oriented architecture rather than MVC. In Drupal, rendering is more like a transformation chain: from database data or XML, through layers of application code, until it is expressed as HTML. In a component architecture, the friend list is the friend list, wherever it appears. You invite it to the party, tell it what numbers to perform, and it's there singing and dancing. You get the idea.
I have more to say about component oriented architectures, but I want to write some code first. More as I have it.