One of the most common mistakes I see people make when talking about web architecture is with regards to MVC. Generally it comes down to a statement such as this:
It's a web app, so we have to use MVC. That way we separate the logic and presentation, which means keeping PHP out of our display layer. All the important projects do it that way.
Of course, such a statement is false. It demonstrates a lack of understanding about MVC, about web applications, about "important projects", and about software architecture in general. Let's try to clarify, with a little help from Wikipedia.
Modular design
Modular design is a generally recognized Good Thing(tm) in software engineering. As in science in general, breaking a problem down to smaller, bite-sized pieces makes it easier to solve. It also allows different people to solve different parts of the problem and still have it all work correctly in the end. Each component is then self-contained and, as long as the interface between different components remains constant, can be extended or even gutted and rewritten as needed without causing a chaotic mess.
I should note that modular design is not the same thing as plugin-based design, which is what many many open source projects use. Drupal "modules" are actually plugins. The Linux kernel, Apache, Eclipse, and many other high-profile projects with "loadable modules" are plugin-based architectures. Plugin-based architectures are not incompatible with modular design and in fact complement it well, but I digress...
Most software architectural patterns are based around the idea that modular design is a good thing, rather by definition. There are lots of architectural patterns for systems depending on what it is they're supposed to do. For interactive systems, the usual breakdown of components is "display component", "data storage component", and "business logic".
MVC
The most commonly-known interactive system architecture is Model-View-Controller, or MVC. Most good desktop applications use MVC or a variant of it, sometimes with the Controller partially merged into the View. In MVC, as the pretty picture at the other end of that links shows, the Model holds data, the View is the part the user sees, and the Controller is an intermediary for business logic. Seems reasonable, right? Now take a closer look.
In MVC, the View component has direct access to the Model. The Controller itself doesn't enter the picture unless there is actual change to the data. Simply reading and displaying data is done entirely by the View component itself. As a result, a system can have many View components active at once, all reading and displaying data in a variety of different ways, even on different systems or in different languages or different modes (GUI vs. textual vs. web). On the flipside, however, that means the View component has to have some rather complex logic in it. It needs to know how to pull data out of the Model, which means it needs to know what the data structure is (or at least a rich API in front of the Model). It needs to be able to handle user interaction itself, with its own event loop.
Well, that rules out most would-be web-MVC setups. One of the most common cries of such systems is to "get database stuff away from HTML". Instead, everything is handled through a smart controller that uses a template layer to render and display output. That's not a bad design necessarily, but it is not MVC. If the display component does not have direct, random-access, pull-access to the data store, then it is not MVC.
PAC
A less publicized but still widely used architecture is Presentation-Abstraction-Control, or PAC. The two main differences between MVC and PAC are that in PAC the Presentation component is "dumb" while all the intelligence resides in the Controller and PAC is layered. Again, see the pretty picture.
You'll notice that the Presentation and Abstraction components never speak to each other. The Controller takes input, not the display component. The Controller has all the business logic and routing information. The Presentation component is essentially just a filter that takes raw data that the Controller pushes through it and renders it to HTML (or WML, or XML, or text, or an icon in a graphical monitoring system, or whatever). It's just a templating system.
The classic example of a PAC architecture is an air traffic control system. One PAC Agent takes input from a radar system about the location of an incoming 747, and uses the Presentation component to paint a picture of that blip on a canvas (screen). Another Agent independently takes input about a DC-10 that is taking off, and paints that blip to the canvas as well. Still another takes in weather data and paints clouds, while another tracks the incoming enemy bomber and paints a red blip instead. (Er, wait...)
The Web and Drupal
A web application doesn't map nicely to either MVC or PAC. There's no consistent event loop for the View component of MVC. For PAC the input is coming from the same source as the display, that is, in via the Presentation layer (kinda). Most web applications I've seen (and written) tend to use a sort of hybrid approach, which then gets (wrongly) called MVC. I blame Sun for that confusion, mostly, but there's enough blame to go around, too.
I'm going to pick on Drupal here because it's what I'm most familiar with, but this isn't a Drupal-specific observation. Drupal is very much a PAC architecture. In fact, it's a rather good PAC architecture. The menu system acts as the Controller. It accepts input via a single source (HTTP GET and POST), routes requests to the appropriate helper functions, pulls data out of the Abstraction (nodes and, in Drupal 5, forms), and then pushes it through a filter to get a Presentation of it (the theme system). It even has multiple, parallel PAC agents in the form of blocks that push data out to a common convas (page.tpl.php).
That's all well and good, but we need to remember, then, that Drupal is a PAC, not MVC framework. If Drupal were an MVC framework, then theme_* functions would have node_load() calls scattered throughout them. That's one reason why, for instance, Adrian's FAPI 3 plans scare me. He talks in his presentation about "a modified MVC but with the Model and View somewhat merged". Well, to start with Drupal isn't MVC in the first place. Secondly, the Model and View are the last pieces you want to merge. Merging a thin Controller into a thick View makes some sense, but merging a rich Model and rich View together makes a rich mess. That loses the separation of data and display that was the whole point in the first place.
Currently the closest Drupal comes to MVC is the Panels module. Panels allows the site admin to set up a custom layout with custom regions and then pull blocks, Views, or nodes into it in those regions. Currently that's the only real pull-based logic that Drupal supports for display given the active discouragement of database access (even via accessors like node_load()) in theme_functions and template files. Even that, however, is still limited to specific panel pages. There's no supported way to randomly pull a block into a node page, for instance. I know Earl "merlin" Miles is deeply engrossed in Panels 2.0, The Next Generation, but I don't believe it currently involves turning Panels inside out. He is, of course, welcome to correct me if he does. ;-)
There's also the Viewfield module for turning a View into a field of a node, but as cool a concept as that is it's still PAC thinking, or at best a very weird hybrid muddle.
Conclusion
There's more to say on this subject, but it's getting late so I will find a convenient stopping point for now. When thinking about your web applications, though, try not to fall back on the default "separation is good so we're using MVC which means separation" logic. Only the first part of that statement, "separation is good", is true. There are lots of ways to build a modular system, all of them appropriate in different places. MVC is not the only, nor even the most widely-used of them. If you aren't calling your data store directly from your display layer, in fact, you're not using it at all.
I'll be back next year with more thoughts on how to address the MVC vs. PAC question, and the impact they have on team development processes. Until then, Happy New Year and Happy Coding!
Nice refresher Mr. Garfield!
Nice refresher Mr. Garfield!
You completely misunderstood me
You quote me trying to explain what we currently have. Those two layers need to be unmerged, not merged.
The data model will be a lot thinner than the current fapi structure (ie: not have all that unnecessary nesting that we have to recurse through to try and find the actual structure of the input _POST).
I believe that the view and the model are two separate data structures , where we currently have only one (this is related to the fact that the input fields are added to the form array, and not just representations of the data type).
Not sure whether this is PAC / MVC, i was just explaining it using language that a lot of people could understand (other than people splitting hairs about terminology)
If so, I apologize
It's possible, since I only saw the slides and wasn't at the presentation. If so, then I apologize. I agree that Drupal needs a cleaner separation of its internal structures. However, I disagree that it's just "splitting hairs about terminology". Understanding what it is you're building is very important in making sure you build it well. Just because Drupal has, or is moving towards, a 3-part split in its architecture doesn't automatically make it MVC. I'd much rather see Drupal become an even better example of a good PAC architecture than become a PAC/MVC hybrid through confusion over which is which. I've worked with systems that were, and they were not pretty.
Similar observations for TYPO3
Hi Larry,
searching google for the combination PAC and MVC I stumbled upon this interesting entry. I was smiling because a few days a blogged very parallel observations for the TYPO3 WCMS. But my focus is upon the tree aspect of PAC in comparism to MVC.
http://t3flyers.wordpress.com/2007/08/06/the-presentation-abstraction-c…
The PAC tree is important in TYPO3. It's configured by TypoScript and it is the central principle of TYPO3 component architecture -- nested components -- while Drupal has a comparingly flat component architecture like Nuke.
http://upload.wikimedia.org/wikipedia/commons/4/4a/Pac-schema.png
If you say that web applications are not strictly MVC because they seperate model and view by the controller you are right. I think that is the reason, why they call this model MVC2. IMHO there is no need to speak of PAC as long you don't need a tree of nested components.
Regards
Elmar
Microtemplates
H, Elmar.
I don't know from Typo3 or Nuke's architecture, but Drupal isn't really "flat". I usually refer to it as micro-templating. You theme (template, presentation component) one very tiny piece of data, then aggregate those pieces into another, larger component (again with a template, presentation component, etc.), then piece together those larger components the same way, etc. until you get to a full page. You can then override the theming/templating anywhere along the line you want, which is (partially) where Drupal's "bendy-ness" comes from.
I'm not sure which "they" you mean or which architecture you're calling "MVC2". If you mean the Rails-style design, then the rails pundits need to figure out their terminology because I've never seen it called that. I also increasingly dislike the Rails-style architecture the more I work with it. :-)
PAC - Microtemplates
Hi Larry,
if Drupal has this nested component technology, I share your position, that it has a PAC architecture.
In this case the question is: Why doesn't Drupal make use of that power given by PAC to offer full freedom of creative design? Why is it shipped with this tedidious, cheap 3-columns-of-boxes look of nuke? Why doesn't it exhaust the given options? Got it stuck half the way?
MVC2 is a term to differ classical MVC of GUI from the webbased MVC design. It's the variety of MVC, that you define to be no MVC at all, because the view isn't updated from the model without help of the controller.
The MVC2 pattern alone is IMHO not enough to make a PAC. Nested nodes with a stand-alone character (agents) have to be part of the game.
I think it's good to have the MVC2 term, to point out the difference, until better terms are given. Both terms MVC2 and PAC are not that perfect names, that make the patterns directly obvious.
Kind Regards
Elmar
Default vs. power
Well, most sites do still use a "holy grail" style layout (three column with two sidebar). The bigger challenge is that doing a content-agnostic fancy design is really hard. Most really "out there" designs are very site-specific. I've been involved in a couple of them, such as:
http://artsci.wustl.edu/
or
http://www.theromansarecoming.com/
I'm working on another one that should be launching in the next few weeks that, design-wise, should knock your socks off. :-)
I'm also looking to work on formalizing that concept with more "explicit PAC" design in Drupal 7, but we'll see how that progresses when the time comes.
3 tier architecture
PAC sounds amazingly like the commonplace 3-tier architecture used in the 1990s for many, many systems.
Nice article, Larry. This is something to which clarity needed to be brought.
I've also heard it said that MVC not only is not what most web applications are using, but is the wrong choice even if possible. An event loop is hard to achieve in a web browser using stateless HTTP requests. AJAX-like technologies and Flash, etc. could obviate that, perhaps.
Exactly!
Yep. True MVC requires an active View layer with bi-directional communication. At best, that means the View layer is sort of straddling the browser and server. Icky. The closest thing to that I know of would probably be Comet, although I've not worked with it.
It's not surprising that PAC sounds like the classic "3-tier architecture", since it originated in older systems like air traffic control (the canonical example) that were designed in the 60s and 70s and needed to always work, thank you very much, and aggregate a lot of separate bits of data.
"dismembered that concept" ?
Saw your link-with-attitude elsewhere and it caught my interest. Unfortunately from reading this, you don't seem to understand MVC (or PAC for that matter). And you are mashing up modularity, separation and dependency.
Let me get the hight level definition of MVC out of the way first - MVC defines two separations. The first is a layer separation between the Domain/Business layer and the Presentation layer. The second separation is between the Controller and View within the Presentation layer. The Model is typically an object in a DomainModel. The Controller mainly deals with input. The View mainly deals with output. The layer separation defines the dependencies with the Model -- though all the rules can and are bent. Though you may say "that's the same thing I said" it is not. The business logic is in the Model. The View is the logic that generates what the user sees. The Controller is less and intermediary and more a selector.
The View does not have an event loop in it for user intereaction -- never heard of such a thing. Dealing with the Request is definitely a Controller responsibility.
From your description of how the View gets data from the Model it sounds like you might think the View gets data directly from the DataSource, or that the Model and DataSource are the same thing. The DataSource should be in a layer below the Model. The View does not have "direct, random-access, pull-access to the data store". Not sure where you go that idea, but the Model is the "rich API".
A "smart controller that uses a template layer to render and display output" can certainly be MVC. Again, not sure what "smart" means, but commonly the Controller will select the appropriate Model and and View, and pass the Model to the View. The View in your example would then be one of the many PHP template engines available. Don't mistake that engine (and all its presentation logic) with the template data.
And finally, MVC is currently mainly used for web applications. Long running applications with many concurrent modes and inputs have moved to patterns like PAC/HMVC to deal with the complexity. Web applications are still nicely request/response focused. The separations in MVC are still a best practice and survive in patterns like PAC. The many vitriolic statements you hear are typically about a specific framework's implementation of MVC. It used to be Struts, now it's Rails. Both advanced and shook-up the discussion. The separation and dependencies defined in MVC are very simple, but they have far reaching effects on implementation -- hence all the disagreements and all the MVC frameworks. But misstatements and misunderstandings like you present do not advance the discussion.
Long-standing literature
GoF, page 4 and following, plus current academia.
My point is that "MVC" existed long before the Web, and was designed for "active" interactive systems, not request-response systems. The View has an Observer relationship with the Model itself. That is not the case in most would-be Web-MVC frameworks that I've seen (regardless of their other respective qualities or lack of qualities).
Calling any form of 3-part separation MVC does not advance the discussion, which is precisely the point I'm making.
I know what the literature says
I have read the Reenskaug, GoF, Fowler, and many others about MVC (not sure who "current academia" are?)
I did not say that MVC was designed for web applications -- it was created before they existed. I said it is "currently mainly used for web applications" and that the applications is was originally designed for have moved to patterns/design that different variations of the idea (PAC, MVP, etc.).
Nowhere did I call "any form of 3-part separation MVC." I described the specifics of the MVC layers, separations and dependencies in detail, as well as the responsibilities of the parts, to correct your misstatements.
ah. some dissent.
This whole conversation is so refreshing. Finally some people who don't click their heels and salute the MVC acronym!
I remember when I first read the MVC definition in Java/Swing docs. I felt a little bit queasy about it, although I had to agree somewhat.
My more recent experience is that a prospective employer won't hire you unless you pledge fealty to the MVC concept. I always do.
But when you hear their definition of MVC, it's always a little different than you last job's.
And when you actually see the code base, it doesn't really follow... MVC, or even their own description. Often there are directories or files named 'model', 'view', 'controller' or something like that. But the view and controller are often intertangled (for instance, both are in the browser AND the server in webapps). And, often, the interpretation seems to be:
I've always mistrusted definitions of MVC that didn't recognize a hierarchy. The code for a checkbox can be thought of as MVC - the view draws it, the controller handles clicks, and the model is that one bit the user switches on or off. Same for a scroll bar or other small widget. The resulting 'model' might be used by the view (scrollbar) or a controller (to interpret some input) or might go directly to the model (a bit stored in the database). I won't be satisfied until I get a design pattern that takes that into account.
cool - kind of puts MVC in
cool - kind of puts MVC in perspective. I think web development is really a little bizzare to say the least.