Model-View-Controller ~ Implementation for Java


There are many different variations on the implementation of the Model-View-Controller (MVC) theme. Some programmers have even declared it obsolete or have moved on to new variations such as  Model-View-ViewModel (MVVM). Regardless, the main benefit of the various schemes is separation and encapsulation.

This text details an implementation of MVC useful for Java. It provides a structure that encapsulates keyboard and mouse events with the GUI, as both functions are specific to the Java language and somewhat tied together.

The Variations

The original concept of MVC is outlined in Model-View-Controller Overview by the creator Trygve Reenskaug. From this paper, various deviations have been expounded upon.

The main line of variation involves which component can access which component. In some implementations, the Controller can access both the Model and the View, the View can access the Model, and the Model has no access to any other component. In others, the Model accesses the View instead of the other way around. Basically, the fewer access paths the better.

The Model

The Model is a group of classes or functions which encapsulate the data. This is often a Package in Java. The Model handles saving and loading the data from persistent storage. It also handles setting and getting data in the local memory. It does not actually apply any algorithms to the data or perform calculations. It simply holds the data and controls access.

How it handles the data is unknown to the outside classes. It may hold it in an array, a data base tree, or an SQL database…perhaps even an external one accessed via the network. Similarly, it may save and load the data to and from a file or a remote database.

The View

In the implementation described in this text, the View displays the data sent to it from the Model and captures keyboard and mouse events. It does not process the events, it simply passes them on to the Controller. It also handles commands from the Controller which control the arrangement of the view objects, such as opening and closing windows.

The reason this particular implementation combines keyboard and mouse events with the View is because in Java, and many other platforms, those events are tightly coupled to the GUI. For instance, mouse actions and keyboard shortcuts are often bound to a specific window. Swapping out the GUI portion of the View inevitably requires modifying the accompanying event handling system, so it makes sense that they are in the same package.

One important rule is that the View never acts on a keyboard or mouse event directly. For instance, it does not open a window when the user clicks on a button designated for that purpose. Instead, it sends the button click action to the Controller and the Controller then sends back a command to the View to open the window. This keeps the Controller fully apprised of the state of the View.

The Controller

The Controller ties all the components together and controls the action. It sends commands to the Model and the View to load and save data, set and get data in local memory, update the View from the Model,  and to adjust the View arrangement.

The algorithms for processing the data are part of the Controller, such as sorting and filtering.

The Benefits of MVC

Three significant benefits of using the MVC pattern are:

  • simplification of porting between platforms
  • simplification of team programming
  • simplification of debugging and modification

Porting

The process of porting between platforms is simplified because all of the required modifications will be localized to the View. There is less chance of corrupting the handling of data as there is no need to change the functionality of the Model or Controller.

In non-MVC structures, accesses to the GUI are scattered throughout the entire code. These accesses will generally be specific to the platform, such as setting the text in a label. The command to do this is different between platforms, so porting would require hundreds of decisions by the programmer as to the proper command to use to properly effect the same effect in the new platform.

For example, in MVC the command to set a warning message might be:

view.setWarningMsg(“Alert!”);

In a View for Java, this command might be handled by:

warningLabel.setText(msg);

whereas for a system only having Console output it might be handle by:

System.out.println(msg);

Similarly, the message might be printed on an LCD display via an I2C bus or a remote display panel via an Ethernet link.

Changing this one function setWarningMsg in the View is much easier than changing hundreds of calls throughout the entire program.

Team Programming

MVC allows the work to be cleanly divided between programmers. Up front, the commands between components are defined. Each team can then design their assigned component to handle those commands…either receiving or transmitting them.

It is easier to program in teams when there is minimal crossover between components because changes to the code don’t overlap.

Debugging and Modification

It is much easier to find bugs when the various elements are separated. For example, when every call to set a data element must go through the same function, it is easy to set a break point in that function to catch every invocation. Otherwise, any line in code could be causing a data corruption at any time. This is actually an extension of the data hiding concepts built into Object Oriented Programming.

Likewise, modification is simplified when the changes can be localized to a specific package. In a properly designed MVC implementation, tweaking the GUI does not require changing hundreds of different pieces of code scattered throughout the entire program. Additionally, it is easier to visualize where changes are required when the functionality is sorted to specific packages.

The Drawbacks of MVC

Implementing MVC requires a little planning up front and a bit of preliminary code here and there. In the long run, the extra code often reduces the overall amount required.

In non-MVC programming, writing something to any window from anywhere in code is quick and simple. In MVC, a function must be first be created in the View and a protocol for transmitting the data must be fleshed out. Afterwards, however, the MVC method greatly simplifies tweaks to the GUI, such as changing the color used for displaying a warning message. The fix must only be applied to the one function in View rather than throughout the code.

Making Functions Generic

Functions used in MVC should be generic and not refer to anything specific to a particular platform. For instance, a Java command such as warningLabel.setText(msg) is specific to the Java GUI and should not be used. Rather, a function in View should be created such as view.setWarningMsg(msg). The meaning is much more flexible and could imply setting a message on the screen, on an LCD display, or even on a paper printout.

MVC Diagram

For the implementation described in this text, the following diagram applies:

In this implementation, the View does not request data from the Model. The Model sends data to the View as instructed by the Controller. When a change to the View occurs, such as the resizing of a window, the View notifies the Controller which then commands the Model to update the data in that window. The Model can query the View as to the amount of data required by the display component.

Note that the arrow lines in the diagram do not imply one-way access. They only specify which component is aware of which component. For example, the Model has a pointer to the View, but the View does not have a pointer to the Model. The Model can call commands in the View to retrieve data such as the number of lines in a display and it can call commands to send data to that display. Thus the Model can both send and receive data to and from the View.

It is possible to adjust this implementation such that the View does not have a pointer back to the Controller. In such case, events could not be sent to the Controller, rather it would have to continuously poll the View for new events. This is a bit inefficient and would require the View to store the events in a buffer to make sure that none would be missed between calls from the Controller.

Real Life Example

A very concrete example where MVC is beneficial is a case where software is being implemented into a physical device such as a robot. It is quite handy to be able to simulate the robot on a laptop, and then run the same software on the robot itself.

For this case, two different Views are created: one which displays on the computer screen and one which displays on a simple LCD screen. The robot Controller code will display useful messages to reflect various states. When the code is being run on a computer, these messages will be displayed on the screen; a graphic of the robot’s internal map of the world might even be displayed. When the code is run on the robot, a different View is used which might display messages on a simple LCD panel; calls to display the map might be ignored altogether if a suitable display is not available.

For saving and loading data, the computer based Model might save to a local file whereas the robot based version might save to a local file or might communicate with a remote file server via WiFi to allow for a larger database.

January 7, 2017

Mike Schoonover
mike@ntcorin.com

LinkedIn Profile

Reference:

Model-View-Controller Overview by the original creator Trygve Reenskaug.

, ,

Leave a Reply

Your email address will not be published. Required fields are marked *