Monday, February 9, 2009

My Claim: "MTV" Is Silly.

repoze.bfg's creator, Chris McDonough, in an informative and corrective comment to my last blog post, among other things disagreed with me about my assertion that "repoze.bfg doesn't provide a model story; it provides a traversal story."

I'm afraid I didn't communicate myself well enough. He might still disagree, and I might still fail to make my points clearly, but I found this the most interesting observation I made, so let me try again.

  • I think applying Model-View-Controller to client-side application frameworks makes sense. MVC actually makes sense, with a reasonably clear delineation of responsibilities, when you look at Cocoa, for instance, or even in some of the more recent JS frameworks (Sproutcore, for instance).
  • All of the reasonably recent web frameworks out there with which I am currently even vaguely familiar (Zope 3, Django, RoR, bfg, Pylons) have a model and something responsible for rendering. The rendering usually goes out to a template, but not always. It's not really cooked that you have to, and usually that's regarded as an advantage and a flexibility. "Render however you want! Use whatever library you want!" So, the heart of the system is Model-View. The Controller isn't there, and the Template is an implementation detail of the View. "Model-Template-View" or "MTV" just seems silly to me. I'd prefer it if everyone acknowledged that our web frameworks usually just have "MV," and move on.
  • bfg doesn't care what it is traversing. Pretty much, give it things that it can use the __getitem__ protocol on, and then when it has consumed the path, it'll adapt to a view class. The __getitem__ bits could be a model...or not! What if your data model didn't jibe with your URL model? That's completely reasonable, and the routes guys have plenty of examples in their apps because of how they think about URLs. What if you like the __getitem__ pattern for your URLs, but your URL story is different than your model. You might build a true MVC system with bfg: pure data-driven models; the bfg traversal system used exclusively over "controller" objects that handle traversal and maybe request (i.e., form) parsing; and views that adapt the controllers to *only* render. Maybe the controllers even optionally have WADL-like contracts based on request inputs.

So, my point was actually not that bfg was cheating in any way--certainly, for instance, nothing like Zope 2. To recap, then.

  1. I find the "MTV" term to be specious generally, whatever the web framework. That's just a criticism of the term, as web framework marketing has adopted it in the past few years. I'd love for it to retire.
  2. interestingly, I don't think bfg is truly tied to the "MTV" model. It doesn't care what it traverses. The MTV model works fine, but a story like what I described, in which the models are maintained separately from the URL space, and the traversed objects are traversal "controllers," would also work well. Then thinking about any additional responsibility of the traversed objects is an interesting exercise, especially in light of REST-ian approaches.

So, yes, Chris is right, from one perspective, bfg is as much MTV as anybody else. That's fine. I'm just railing against the term, and saying that bfg can be used for more than just "MTV".


Chris McDonough said...

Hi Gary,

Yeah. You're right on "MTV" being silly. It really is just "MV". Templates in BFG are only invoked by user code by views, the framework during a request really knows nothing about templates. A view just returns a response; it might happen to be rendered by a template, but the response handler doesn't care.

In calling BFG an "MTV" framework in the docs, I was just trying to get out of the "MVC" trap mostly by calling it something else: most "MVC" frameworks really aren't as far as I can tell. I think "MTV" is *more* right than MVC in this respect (but again, you're right, it really is just "MV"). It was also easy to quote the Django docs. Maybe I'll change the docs to say what I really think about it.

I don't know where "controllers" fit in during traversal. I think this is all just terminology really. The real point I was trying to make is that, while any __getitem__ invoked during traversal can do anything and have arbitrary side effects, the only truly meaningful thing it can do is return another "model" object. That model object might be fabricated from whole cloth and not represented physically within some hierarchy of course. But model __getitem__ methods don't have access to the environment, or the response, or the request, so they really just can't do very much to influence request processing except return another model object, unless you work really, really hard to honor side effects at the end of traversal. This is by design. In particular, a view *must* do the work at the end of traversal; if a view cannot be found for a returned model object (the "context"), a 404 is returned. I gather you probably know this already, so maybe we're just disagreeing about terminology.

FTR, BFG doesn't just do traversal. It also has a subsystem that allows you to bypass any sort of traversal altogether. When you use BFG in "urldispatch" mode, you don't really need any sort of hierarchy to traverse over; instead a model object is created based on a URL pattern. This is useful in cases where you have flat data that doesn't really lend itself to a hierarchy (an RDB, etc.).

I hope you continue to mess around with BFG, it would be cool to have you around. ;-)

- C

James Bennett said...

From the point of view of someone who's primarily doing Django, I personally see the need for some sort of term like this as a necessary evil.

Even though most of the successful new frameworks and libraries for web apps from the last few years have made significant breaks with MVC, they still separate concerns in a way which (if you don't look too closely) resembles MVC just enough that people start asking what's going on and wanting some term they can apply to it.

Mix this with a bunch of folks coming in from the Java and .NET worlds who've spent far too much time learning that MVC is the One True Way to do web apps (when in fact real MVC doesn't really fit the web), and we're basically stuck having to invent a term in order to keep those folks from walking away as soon as they notice it's not "real" MVC.

I'd dearly love to live in a world where we could just say "hey, MVC's not all it's cracked up to be for web apps, and what's really important is being able to separate your concerns in sensible ways", but sadly we're not quite there yet.