The Model-View-Controller Framework

The MVC framework is a generic implementation of the Model-View-Controller design pattern.

MVC-based Applications

The MVC framework supports diverse desktop applications:

Notes

·       Applications built on top of the MVC framework are called customizations.

·       Developers who build customizations are called customizers.

MVC Use Cases

MVC-based applications have three menus: File (red use cases), Help (green use cases), and Edit (yellow abstract use case):

Notes

·       The Save As use case prompts the user for a file name.

·       Save is a special case of Save As because it only prompts the user for a file name the first time it is executed.

·       If there are unsaved changes to the application data, Quit, Open, and New prompt the user to save them.

·       The Edit use case is abstract because it depends on the application. For example, a word processor might provide three ways to edit a document:

Example: Stoplight Simulator

Like most MVC customizations, the stoplight simulator's user interface is divided into four sections. At the top is the title bar, below that is the menu bar with three menus: File, Edit, and Help. The Edit menu contains a single menu item labeled "Change". Below the menu bar on the left side is a control panel with a single button also labeled "Change". To its right is the stoplight view that displays the stoplight's current color:

Clicking the Change button or selecting the Change menu item creates a Change command that is sent to a command processor where it is executed. Executing it changes to stoplight's color according to the sequence green, yellow, red, and back to green.

Selecting "Help" from the Help menu displays the message dialog:

Selecting "About" from the Help menu displays a copyright notice:

Selecting "New" from the File menu displays a warning:

Selecting "Save" from the File menu displays a File Chooser dialog:

Model

Application data and logic is contained in an extension of the framework's Model class. In the Stoplight Simulator the application data is the current color of the stoplight. The application logic is a change method that changes the color according to the specified sequence. Both are stored in a Stoplight class that extends Model:

Notes

·       Every time a model property changes—such as the color of a stoplight, the model needs to broadcast this change to interested listeners. (This is just the Publisher-Subscriber pattern.) The model inherits the listener notification machinery from the Bean class.

·       We need the ability to save Application data to a file and read it back later. This is easy in Java. We simply declare that Bean (and therefore Model) implements Java's Serializable interface and Java takes care of all of the nasty details of serialization and de-serialization. (Why is this hard?)

·       But which file should be used? The Model class stores the name of the file. Initially, this is null, indicating that the user has not yet specified a file name. This happens the first time the user selects "Save" from the File menu. On subsequent saves MVC won't pester the user for the file name. The user can select "Save As" to change the file name.

·       Every time the user modifies Application data, the unsavedChanges flag is set to true. Every time the user selects "Save" from the File menu the flag is set to false. If the user selects "New", "Open", or "Quit" from the File menu when this flag is set to true, he will be prompted to first save the current model.

·       Lastly, the Model class is abstract as a reminder to customizers that application data and logic needs to be specified in an extension of the Model class.

View

A model may have one or more associated views. A view graphically displays the model data.

Notes

·       Recall that the purpose of the Model-View-Controller pattern is to decouple presentation logic (i.e., how the application data is displayed) from application logic. This is done so that changes to the presentation layer don't require changes to the application layer. Thus, the View has a reference to the model, but not vice versa.

·       How does a view know when the application data has changed? We use the Publisher-Subscriber pattern. The model is a publisher (implemented here as a bean), while views are subscribers (implemented here as property change listeners). In our example, when the stoplight changes color (by clicking the "Change" button, say), then it calls the propertyChange method of each subscriber/listener. In our case there is only one listener, the stoplight view.

·       View extends Swing's JComponent class. A JComponent is a very general GUI component. It has a paintComponent method that can be overridden to paint anything at all in the component. Programmers don't call this method directly. Instead they call the repaint method which schedules a call to paintComponent.

·       The entire sequence can be represented using a UML sequence diagram:

o   A sequence diagram shows the interaction between objects over a period of time.

o   In this diagram we see three objects at the top. The lines hanging below them are called lifelines. Time flows down the lifelines.

o   Arrows indicate message exchanges between the objects. In most cases messages are method calls and returns.

o   Activation boxes (the long skinny boxes) represent the period of time a method  is active.

Command

The MVC framework uses the Command Processor pattern (aka Commands-as-Objects pattern). Clicking a button, selecting a menu item, typing in a text field creates a command that is executed by the command processor.

Notes

·       Only Edit commands use this pattern. File and Help menu commands are baked into the framework.

·       The MVC Command class is abstract because the framework doesn't know what the edit commands will be.

·       Stoplight Simulator only has one edit command: ChangeCommand. It will call the stoplight's change method:

public class ChangeCommand extends Command {
  public ChangeCommand(Model m) { super(m); }
  public void execute() {
     StopLight light = (StopLight)model;
     light.change();
  }
}

·       Clicking the "Change" button creates a new instance of this class and passes it to the CommandProcessor's static execute method:

CommandProcessor.execute(command);

·       Usually we implement the command processor as a singleton—i.e. as a one of a kind object rather than a class. This requires a programming trick in Java. (How do you enforce the constraint that a class only has one instance?) Instead, we simply make the execute method a public static method that can be called from anywhere in the program.

·       Currently the command processor is pretty useless. In future implementations this is where we would add undo and redo stacks.

AppPanel

The AppPanel is the glue that brings everything together—the model, the views, the menus, etc.

 

Notes

·       Swing uses the Composite design pattern to build GUIs:

·       AppPanel extends JPanel by adding a reference to the model, a set of views, and a reference to the JFrame that serves as a desktop window that frames the panel.

·       The AppPanel is an action listener that listens to all of the buttons and menu items. This is the Publisher-Subscriber pattern again, but this time the buttons and menu items are the publishers of action events.

·       The AppPanel also listens for property change events fired by the model. This is sometimes needed when components such as text fields and labels need to be updated when the model changes.

Abstract Factories

Recall that the Abstract Factory pattern is used to decouple the construction of an assembly (the AppPanel in our case) from the construction of its components (model and views). Notice how this is used by the AppPanel to create the edit menu and execute edit menu commands without the need to know anything about the customization:

·       AppPanel.java

·       StopLightFactory.java

Customizing the AppPanel

Customizers will need to customize the AppPanel by adding views and controls. This involves using nested layout strategies. For example:

·       StopLightPanel.java

Beans and Utilities

Recall that a Utility (aka Service) is a class containing only public static members (methods and variables). Usually these members are related, but they are not regarded as describing the state and behavior of some class of objects. It's simply a recognition that it's not always beneficial to regard functions as methods.

The MVC framework provides utilities for I/O operations.

·       Utilities.java

Mvc also contains a reusable Bean class

·       Bean.java

Exercises

Complete the implementation of the MVC framework.

Test your framework by completing the implementation of the Stoplight Simulator.

Patterns Used

·       Model-View-Controller

·       Abstract Factory

·       Publisher-Subscriber

·       Composite (for nested JPanels)

·       Strategy (for JPanel layout)

·       Utilities

·       Singleton

·       Command Processor

Resources

·       MVC + Java Fragments (for Star UML)