AJAX and the clean Model-View-Controller

I’d like to say I’m a strong believer in MVC, but I’ve never quite gotten it to work cleanly for me. There are two problems it doesn’t solve for me, and those are the two that I’m looking for my pattern to solve.

First, there’s the issue of what to model in the Model. Do I model the back-end data/services/objects or the UI data model? Note that these are different. The UI model is inherently about what’s being displayed. The back-end model is about the inherent behavior of the back-end system. You can have 10 different UIs sitting on the same back-end. Separate, different.

Having services and UIs differ is a valid and good thing. Look at all the interesting mashups. Does this mean you should explicitly not model the UI in your backend? The Model is just the back-end model? Or does the Model actually live in the client, and I’ve got it all backwards?

I think the point of the Model is to model the UI, but being primarily a back-end guy, first and foremost I’d like to have clean APIs to my services. Someone smarter than me will create a better UI than the one I’ll ship out of the box.

Hmm. So I’m going to model the back-end, and with Laziness as one of my first order principles of good design, I’m damned if I’m going to have two different models, so I’m going to neglect the UI model. But if I don’t model the UI data, who will? Feels like I’m not doing MVC right.

Ok, so the Model has me conflicted. Perhaps the View will clear it all up for me.

What is the View, exactly? In the Web world I tend to think of the View as the HTML. I think the point is to have the model be free of excess code, a nice pristine representation of the UI I can hand to an HTML guy to make pretty. Is this right?

But Views never are clean of code. They’re messy. They’re gooey. That’s their nature. Views change based on the state of the app, the nature of the data, etc. You must be able to express if/then/else, calculate things, do all sorts of messy nonsense. Perhaps someone smarter than me can do that cleanly, but I always end up with code and presentation all together.

Ok, so where am I now? I’m not sure what to Model, and my View is getting messy.

Well, the controller I’m ok with. I understand what that is. That controls state.

Because of all this, I can never get MVC quite right. I end up in PHP land, embracing the messiness. Throw the code into the template, mix in some of the controller in there too even though I know I shouldn’t. The MVC way won’t be clean for me anyway, so let me at least get the job done quickly. PHP is great at that. I think Dave Megginson is expressing a similar sentiment here?

Recently I’ve been playing around with AJAX, and things are becoming clearer.

My Model will be my services model, not my UI model. The two are very separate in very clear ways: they’re written in different languages in different places, one on the back-end, one on the browser. No problems there.

My View will be my code in the browser. It’s messy. It’s ugly. I really don’t like Javascript. But at least I know what goes there. The presentation code and the presentation are inexorably mixed together (the former manipulates and modifies the latter), and that’s just how it is, so I don’t worry about the cleanness. But it’s clean in that my interfaces to my back-end are well defined and not mixed in with my View.

How about the Controller? This one becomes a little more cloudy for me in practice, because I’ve separated out the View completely, so really I’m controlling my back-end state. Which is different from controlling my View state. It becomes more an issue of validating that the state as I know it on the back-end is the same as the state on the front-end. Or, more acurately, to validate that the state transitions the front-end requests are acceptable to the back-end.

There you have it. I’m on my third AJAX project / experiment, and I find I’m spending most of my time on the design of the APIs and the state transitions. That feels right. If I nail that, I can build a new UI completely independently. Better yet, someone else can do it. I know where all the code goes. Things feel clean.

I’m not really sure this is even the MVC anymore, or that I ever had MVC right, but it fits my brain better than other solutions I’ve tried before. And I’ve tried a few. Perhaps the problem is I’m applying MVC to the wrong part of the problem?

What do you think? Someone who understands MVC please set me straight.

1 Comment so far

  1. Ryan Brown on September 27th, 2007

    I am by no means a master of MVC, but three things jumped out at me as I read your post. My responses come from a book called “A System of Patterns”.

    1. You said, “First, there’s the issue of what to model in the Model. Do I model the back-end data/services/objects or the UI data model? Note that these are different. The UI model is inherently about what’s being displayed. The back-end model is about the inherent behavior of the back-end system.” A System of Patterns says that the Model contains the “functional core of the application” (p 127), encapsulating the appropriate data and providing methods that do app specific processing. The way I read this, the Model does not model the UI at all. The UI is actually the Controller component of the MVC pattern. “The user interacts with the system solely through Controllers” (p 127). If you have 10 different UIs relying on the same back-end (Model component), then you’ll be writing 10 different Controllers.

    2. You said, “What is the View, exactly? In the Web world I tend to think of the View as the HTML.” Precisely. The HTML is a View of the data stored in the Model component. It’s true that there may be buttons, text fields, forms, etc. displayed in the HTML, but as soon as a user clicks on something the Controller component is in charge. Perhaps that’s where some confusion creeps in… The View component must collaborate with both the Model and Controller components and therefore will display information from both. Further, “there is a one-to-one relationship between views and controllers.” (p 128) You have exactly one Model component (your back-end) and an equal number of View and Controller components (displays and UIs).

    3. You said, “How about the Controller? This one becomes a little more cloudy for me in practice, because I’ve separated out the View completely, so really I’m controlling my back-end state. Which is different from controlling my View state. It becomes more an issue of validating that the state as I know it on the back-end is the same as the state on the front-end. Or, more acurately, to validate that the state transitions the front-end requests are acceptable to the back-end.” Again, you are on the right track. The Controller component, which is really the functional element of the UI (the visual element being handled by the View component) is a messenger. User clicks a button, so the Controller takes that information back to the Model to either update the Model with new data and/or grab some data from the Model to be displayed. There’s your state change. The Controller component works in both directions. Changes to the Model component are communicated to View components via corresponding Controller components. Changes in a View Component are immediately handled by the corresponding Controller component (which is the UI, after all) and communicated to the Model component.

    There is one major piece to this pattern that you don’t mention but which seems integral. “The separation of the model from view and controller components allows multiple views of the same model. If the user changes the model via the controller of one view, all other views dependent on this data should reflect the changes.” (p 127) You have, I think, pretty much implied this in your post, but here’s the additional bit… “The model therefore notifies all views whenever its data changes. The views in turn retrieve new data from the model and update the displayed information.” (p 127). So, there’s has to be a notification mechanism in place to keep everything synched up. State change must be communicated through the whole application. The book suggests that a registry be kept of all dependent components. Whenever a View is created a Controller will also be created (one duty of a View component is to create and initialize a corresponding Controller), it needs to register itself with the application, so that it can be notified when something changes.

    One more thing. It is possible to completely separate your HTML and your JavaScript. The following chunk is from JavaScript – The Definitive Guide, 5th edition

    — begin chunk —
    Unobtrusive JavaScript

    A new client-side programming paradigm known as unobtrusive JavaScript has been gaining currency within the web development community. As its name implies, this paradigm holds that JavaScript should not draw attention to itself; it should not obtrude.[*] It should not obtrude on users viewing a web page, on content authors creating HTML markup, or on web designers creating HTML templates or CSS stylesheets.

    [*] “Obtrude” is an obscure synonym for “intrude.” The American Heritage dictionary cites: “To impose… on others with undue insistence or without invitation.”

    There is no specific formula for writing unobtrusive JavaScript code. However, a number of helpful practices, discussed elsewhere in this book, will put you on the right track.

    The first goal of unobtrusive JavaScript is to keep JavaScript code separate from HTML markup. This keeps content separate from behavior in the same way that putting CSS in external stylesheets keeps content separate from presentation. To achieve this goal, you put all your JavaScript code in external files and include those files into your HTML pages with tags (see Section 13.2.2. for details). If you are strict about the separation of content and behavior, you won’t even include JavaScript code in the event-handler attributes of your HTML files. Instead, you will write JavaScript code (in an external file) that registers event handlers on the HTML elements that need them (Chapter 17 describes how to do this).

    As a corollary to this goal, you should strive to make your external files of JavaScript code as modular as possible using techniques described in Chapter 10. This allows you to include multiple independent modules of code into the same web page without worrying about the variables and functions of one module overwriting the variables and functions of another.

    The second goal of unobtrusive JavaScript is that it must degrade gracefully. Your scripts should be conceived and designed as enhancements to HTML content, but that content should still be available without your JavaScript code (as will happen, for example, when a user disables JavaScript in her browser). An important technique for graceful degradation is called feature testing: before taking any actions, your JavaScript modules should first ensure that the client-side features they require are available in the browser in which the code is running. Feature testing is a compatibility technique described in more detail in Section 13.6.3.

    A third goal of unobtrusive JavaScript is that it must not degrade the accessibility of an HTML page (and ideally it should enhance accessibility). If the inclusion of JavaScript code reduces the accessibility of web pages, that JavaScript code has obtruded on the disabled users who rely on accessible web pages. JavaScript accessibility is described in more detail in Section 13.7.

    Other formulations of unobtrusive JavaScript may include other goals in addition to the three described here. One primary source from which to learn more about unobtrusive scripting is “The JavaScript Manifesto,” published by the DOM Scripting Task Force at http://domscripting.webstandards.org/?page_id=2.

    — end chunk —

    Food for thought?

    Thanks for the post. I am currently working on a design for a very simple AJAX app and came across this when googling for “ajax model view conroller”. Attempting to answer your questions helps me get a better grasp on the MVC pattern.

    Cheers,
    Ryan

Leave a Reply