The Model-View-Controller Pattern in SmallTalk and partially supported in many Frameworks sought to solve the problem of decoupling the user interface from the datamodel. The MFCV pattern is a refinement of the MCV pattern. The MFCV pattern adds a new object to the relationship called the Facade. This refinement brings the MCV pattern more closely in sync with its actual use by most programmers when using a framework, increases the robustness of the architecture, and speeds development.
Additionally, the Facade class becomes a logical repository for methods that handle user commands.
Also Known As
An alternate terminology consistent with most frameworks would be: Model-Document-Window-Control.
Two things are guaranteed to change over the life of any project: The user interface, and the data structures. Using the MFCV pattern, coupling between the data model and the UI are kept to a minimum.
The MFCV pattern is applicable to any program that has a collection of data and a user interface that acts upon that data. This includes most of today's event-driven programs. It is especially applicable to applications written using a UI framework. When using a typical UI framework the classes defined in the pattern map directly onto typical framework classes.
The classes participating in this pattern are: The Model, the Facade, the Controller, and The View.
The Model class is just a shorthand term for the entire data model used by the program. That is, its really the entire collection of classes that make up the data mode.
The facade class is an implementation of the Facade pattern from the Design Patterns book. It lies between the data model and rest of the system. Specifically, it has the following duties:
The Controller class manages the View objects associated with a UI component, generally a window. It translates actions generated by View objects into commands to the Facade. For instance, a Controller object might translate a particular "ButtonPressed" action from an OK button into an "UpdateData" message for the Facade.
The view classes are the classes that actually respond to user events and turn them into an actions. For instance, a View object for an "OK" button turns mouse clicks into "ButtonClicked" messages.
Each class collaborates between the other classes next to it in the line. The Model collaborates with the Facade, the Facade with the Controller, and the Controller with the View.
How does the pattern support its objectives? What are the trade-offs and results of using the pattern? What aspect of system structure does it let you vary independently?
What pitfalls, hints, or techniques should you be aware of when implementing the pattern? Are there language-specific issues?
Sample Code and Usage
Imagine you want to write a program that allows the user to create a list of named colors. So the data model is fairly straightforward, you have a string and a color. The UI for this might consist of a window with a name followed by a rectangle displaying the color. At the bottom of the window there would be three buttons, "Add", "Change" and "Delete". When the user clicks on Add or Change, a dialog comes up where they can enter a name and edit the Color. Clicking Delete removes the selected color from the list.
So far so good. In most frameworks you would have the following objects:
ColorListWindow is the Controller object for mediating between the following View objects: ScrollingView is a compound view object that implements a View object that can scroll its contents. It consists of a scrollbar and associated View object and is provided by the framework. TextView is a view that displays a string and is provided by the framework. ColorView is a view that displays a rectangle of color. ButtonView is a view that implements a button and is provided by the framework.
ColorEditDialog is the Controller object for mediating between the following View objects: ButtonView is the same button view as above. ColorEditView is a compound View object that implements a color editor. TextEditView is a view that allows the user to edit a string and is provided by the framework.
The data model consists of the objects String, Color, NamedColor, and ColorList. String is the object that represents a string in the framework. Color is the object that represents a color and is provided by the framework. NamedColor is the object that glues a Color object to a String object, and represents the fundamental unit of information used by the program. ColorList is a Collection of NamedColor objects.
ColorDocument is the Facade. It holds a pointer to the ColorList. It has calls that return the number of colors (passed through to ColorList), the Color or name of any color given its index. Also, it has calls to change a NamedColor, to add a new NamedColor, or to delete a NamedColor. Most of these functions are only one or two lines. It also has a function called EditColor that creates a ColorEditDialog for a given color.
Lets look at what happens when the user edits a color. First, the user double clicks on the fifth color in the list, and selects "Change". The ColorListWindow translates this action into the high-level action, EditColor(5). The ColorListWindow is now done.
The ColorDocument receives the action "EditColor(5)". It makes a new ColorEditDialog and passes it "5" in the constructor. The ColorEditDialog creates the necessary controls. It asks the ColorDocument the name and color of the NamedColor numbered 5. It passes that data along to the ColorEditView and TextEditView objects. The ColorDocument is now done until the user hits "OK" or "Cancel".
When the user clicks "OK", the ColorEditDialog retrieves the input data from its views, and destroys the window and its views. It then pass the high-level action "SetNamedColor" to ColorDocument with the right values.
Examples of the pattern found in real systems. We include at least two examples from different domains.
What design patterns are closely related to this one? What are the important differences? With which other patterns should this one be used?