Full Guide: Model-View-Controller (MVC) in Java

99% of software developers, course creators, and even well-known frameworks, misunderstand MVC. The MVC pattern was originally created to help build interactive user interfaces, not backend systems. Its main purpose was to help designers think in terms of the user’s own mental model of the Thing being represented.

Trygve Reenskaug presenting
Trygve Reenskaug. Image Source: Digi.no

Prof. Trygve Reenskaug first came up with the Thing-Model-View-Editor (TMVE) concept while working at Xerox PARC in 1978-79. This idea became the foundation for the Model-View-Controller (MVC) architecture, which was later implemented as a practical design pattern in Smalltalk around 1980.

“The essential purpose of MVC is to bridge the gap between the human user’s mental model and the digital model that exists in the computer.”
— Prof. Trygve Reenskaug

The Thing

The Thing in Thing-Model-View-Editor (TMVE) was the real-world subject of interest:

It could be concrete, like a house or an integrated circuit. It could be abstract, like a new idea or opinions about a paper. It could be a whole, like a computer, or a part, like a circuit element.
— Prof. Trygve Reenskaug

There’s no one “right” way to look at the Thing. There are many ways to create useful abstractions, of the same Thing, depending on what the user needs to see and do.

Later, in MVC, the Thing was removed, and Editor renamed to Controller, but it is still very important to understand this concept.


The Roles of Model, View and Controller

With that foundation, let’s examine the three parts of MVC one by one.

Model–View–Controller dependency diagram. The Model has no dependencies. The View depends on the Model. The Controller depends on both the Model and the View.
Model–View–Controller dependency diagram. The Model has no dependencies. The View depends on the Model. The Controller depends on both the Model and the View.

Model

The Model is the active representation (not passive data) of the Thing inside the computer:

  • It encapsulates business logic and enforces invariants (rules that must always hold true).
  • It provides operations that allow querying and updating its state.
  • It notifies all of its observers (Views) when it changes.
  • It must never depend on either the View or the Controller.

View

The View is a (visual) representation of a Model:

  • It observes the Model and updates itself when the Model changes.
  • It highlights certain attributes while hiding others, based on user needs.
  • It does not contain business logic.
  • It can call methods on the Model to read data.
  • It should not call methods to change the Model’s state.
  • It does not interpret any user input, such as mouse operations and keystrokes.

Controller

The Controller receives user input (keyboard, mouse, …) and coordinates changes to the Model and/or View.

  • It updates the Model.
  • It arranges its own View(s).

In the original TMVE concept, there was also the Editor.

Some views provide a special controller, an editor, that permits the user to modify the information that is presented by the view … Once the editing process is completed, the editor is removed from the path and discarded. — Prof. Trygve Reenskaug (10 December 1979)

Now that we understand the roles of Model, View, and Controller, let’s see how they come together in a real application.


Case Study: Java Swing MVC To-Do List App

Full code: java-swing-mvc-todo-application

To see MVC in action, let’s create a simple To-Do List app with Java Swing. The app allows users to view and manage the Things they care about, in this case their “to-dos”, while keeping data, presentation, and control cleanly separated.

Java Swing MVC To-Do Application Screenshot
Java Swing MVC To-Do Application Screenshot

High-Level Architecture

A simple To-Do app, shown here in a UML Component Diagram…
Models, Views, and Controllers all working together
A simple To-Do app, shown here in a UML Component Diagram…
Models, Views, and Controllers all working together

Models have only one dependency: javax.beans.*, which provides built-in support for the Observer Pattern, to notify Views that have registered with it.

Views use javax.swing.* to create UI elements such as text fields and buttons. They implement javax.beans.PropertyChangeListener to listen for updates from the Model. Views depend on the Model.

Controllers use java.awt.event.* to handle user input by creating java.awt.event.ActionListeners, which manage creating, removing, and editing to-dos. Controllers depend on both the Model and the View.

Use Cases

We have three main use cases:

  1. Adding a new todo
  2. Removing an existing todo
  3. Editing an existing todo
UML Sequence Diagram showing the "add todo item" use case.
UML Sequence Diagram showing the “add todo item” use case.

Models

The Thing we want to model is a to-do list with individual to-do items:

  • TodoListModel: represents the entire to-do list and manages its state.
  • TodoItemModel: represents a single to-do item.

Why selection is in the Model: In our TodoListModel, we manage the currently selected item because this reflects the user’s mental model, i.e. their current focus or working context, not just a visual UI state.


Views

Next, we want to create visual representations of our Models. Each Model can have one or more Views, depending on what the user needs to see. We have one view for the entire list and one for editing an item.

  • TodoListView: displays the entire to-do list.
  • TodoItemView: displays an editor for a single to-do item.

Deviations from original MVC

In the original 1979 specification, Views were purely for visual display, while Controllers directly managed all low-level user input.

In this guide, Views contain interactive Swing components like JButtons, which handle their own low-level events and instead we delegate higher-level events to Controllers. This was a practical adaptation for the Java Swing environment.

Controllers

Finally, we need to handle user input, like adding new to-dos, editing and removing existing to-dos.

  • TodoListController: handles adding and removing to-dos, and manages the lifecycle (creating and destroying) TodoItemControllers.
  • TodoItemController: is an Editor for editing existing to-dos.

Who Still Gets MVC Right?

As I mentioned in the intro, almost everyone gets MVC wrong: developers, course creators, and even entire frameworks. Most online tutorials just regurgitate a shallow definition without really understanding it themselves. And, modern frameworks have watered MVC down into a loose metaphor for “routing + templates + database models.” But that isn’t MVC; that’s simply layered web architecture.

Here’s how frameworks actually compare to the original idea of MVC:

Smalltalk / Squeak MVC (⭐⭐⭐⭐⭐)
Literally the birthplace. True observer-based MVC, live model-view sync, controllers interpret user input.
JavaScript / Backbone.js (⭐⭐⭐⭐)
Revived the true reactive MVC idea in the browser: live model-view sync, however, controllers are part of the view. Closest after Squeak MVC.
Objective-C / Cocoa (⭐⭐⭐⭐)
Models, views, and controllers are real objects, not just request handlers, but all view-model communication is done via controllers.
Ruby / Ruby on Rails (⭐⭐⭐)
Models have business logic, views observe data, controllers mediate, but still request-based.
Java / Spring MVC (⭐⭐)
MVC is mostly a structural metaphor for web layers (not observer-driven): model = ORM entity, view = rendered template, controller = HTTP endpoint request handler
C# / ASP.NET MVC (⭐⭐)
Same as Spring MVC.
PHP / Laravel (⭐⭐)
Same as Spring MVC.

Then Why Did I Use Java?

For better or worse, Java remains the language of choice for enterprise applications. From my own experience at some of the world’s largest fintechs, most enterprise codebases are overwhelmingly Java-based (at least in finance). Java is also the language I know best.

That said, Java is not without its critics: Reenskaug himself noted at Øredev 2009 (10:08), “Java and Simula are not object-oriented, but rather class-oriented.” Consequently, my choice of language may not be the ideal example for demonstrating object-oriented principles such as MVC, but using Java allows this reading to reach the widest possible audience of developers.


Resources

MVC Papers by Trygve Reenskaug

Java Documentation

Framework Documentation


Whenever you use any information, text, code, or images from this guide, always reference back to it as the source: www.Sorn.dev