This page provides a single point of access to all the materials about the MVCS (Model / View / Controller / Services) approach to building Flex applications.
The following MVCS materials are available:
My Adobe Developer Connection article on the MVCS approach, which describes MVCS principles and refers frequently to the ReviewTube source code.
The ReviewTube Example Application. ReviewTube is a working, open-source Flex 2 application that illustrates the MVCS architecture, and it’s probably the best documentation for that approach to building applications. It allows users to create time-based subtitles for any YouTube video, a la closed captioning. These captions become publicly accessible, and visitors to the site can browse the set of videos with captions. Think of it as a “subtitle graffiti wall” for YouTube!
The ActionScript source to ReviewTube. If you want to actually compile and run this, be sure to obtain a developer ID from YouTube, then copy src/com/joeberkovitz/reviewtube/services/ReviewTubeComponents.mxml.template to ReviewTubeComponents.mxml and paste in the developer ID.
The Ruby on Rails server source for ReviewTube. The source is pretty much devoid of comments, and is in no way illustrative of good server design (see caveats below). However, I’m including it for completeness in case anyone wants to see exactly what requests and responses are supported. This is not a turnkey Rails app — I’ve left out things like DB configuration, and if you want to run it, you’ll need to generate a skeleton app with Rails and then drop this stuff in on top of the skeleton, and get your own DB connection config set up.
MVCS: An Approach, not a Framework
MVCS is often described as a framework, but from my point of view it’s really a set of interlocking design patterns that can be realized in many different ways depending on your needs and your specific application. In order to communicate the sense of these patterns, I built a reasonably-sized, fully functional application called ReviewTube that makes use of them.
So far, I haven’t tried to turn MVCS into a generic framework with well-defined APIs, interfaces, etc. My goal from the outset was always to get people thinking about alternative approaches, not to create the “right framework”. I am not sure I believe in a “right framework”, actually. I have a deep-seated suspicion of methodologies and religions. What I am interested in demonstrating is how to think about “right development practice” in a specific situation, and choosing (or even creating) a framework that supports that practice in a disciplined way.
Different applications are suited to different framework approaches. In my experience, as soon as folks see a nice shiny hammer lying around, they’ll naturally try to use it as a screwdriver or a crowbar. That is why I felt a carefully built-out example application was better than an abstract framework: it shows a hammer and a nail working together, not just a hammer.
Since the original MVCS article I have since built a number of ambitious applications. In each one of them I felt it necessary to substantially modify the plain MVCS approach in order to preserve my notions of “right development practice”. Yet, none of these modifications could be said to be general improvements to MVCS: they were specific adaptations for specific cases.
Recent Modifications to MVCS
Invoking Controller methods via Event Bubbling. In recent situations I have been avoiding use of the Singleton pattern for Views to access Controller objects to invoke their methods. The Singleton approach restricts one to a single Controller for the whole application, but in many cases there can be multiple controller instances, each of which is responsible for for controlling its own Models and Views. (For example, imagine that you have a multi-window application in which each window is viewing/editing a similar document or data sources). In the event-bubbling approach, each Controller listens for events on one or more “ancestor views” high up in the display list hierarchy (possibly the Application itself, if there is only one controller). Individual views further down in the hierarchy dispatch these events on themselves, each of which corresponds to a particular action that the Controller is to perform. Thanks to event bubbling, these events “work their way up” to the ancestor view, at which point the correct Controller receives the event and handles it. Jim Echmalian has developed a nice version of this approach in which all these events exhibit the same
type property, which means that a single event listener for this event type is sufficient to connect a set of views to some controller.
Use of Model Adapters. Very often, the raw information in a Model is not what a View needs to show, and using Flex data bindings to drive the View from the Model becomes extremely awkward. A typical example of this issue is a view that shows summarized or aggregated information. For example, a restaurant finder might break down a set of restaurants by cuisine (imagine a data grid showing “Chinese: 5, Japanese: 10, Thai: 12″ in tabular form). Clearly data bindings can’t accomplish this sort of thing. In such situations, and even in simpler ones, it’s often better to build a special “model adapter” that both exposes this modified view of the underlying Model, and which also listens to change events from that model, dispatching change events of its own when its “adapted” properties change in response.
Use of View Mediators. Another important pattern not illustrated by ReviewTube is the use of Mediators, in which View/View and Controller/View interactions are handled by separate objects that “decouple” these objects from knowledge of each other. A typical example is a situation in which maximizing one View of a Model object minimizes other views of the same model. Rather than hardwiring connections between the views, it’s better to create separate objects that listen for events indicating the minimizing/maximizing and coordinate the overall states. Another type of example is one in which a View is fairly generic in nature and some intermediate processing of its events is required to figure out how and when to invoke the proper Controller operations based on user interaction with that View.
ReviewTube Example: Notes and Caveats:
- You cannot seek to a caption location in the video if the video stream has not yet downloaded to that point. This appears to be a limitation of the Flex 2 VideoDisplay component.
- Repeated quick seeks in a live video stream apparently can cause the video display to cease functioning. I haven’t seen this but it’s been mentioned to me.
- This application isn’t intended to illustrate best practices in interaction design. I’ve gotten some useful feedback from designers I know, but I haven’t had time to implement all of it.
- The server has a number of security holes in which it should be making various checks on the session before performing modifications. It stores cleartext passwords. It doesn’t return reasonable error responses in all cases. Don’t take the server as any sort of example of good practice! This project was all about client design.