Model View Controller is a common design pattern used in
most applications that have a graphical user interface.
You can use this pattern in pretty much any kind of
application: a web application, a Java application,
a smart phone application, etc. The premise is that
you separate the code for the data model, the actual
interface, and the logic that works behind the scenes.
This allows you to create more modular and re-usable
code while following the
SOLID principles.
The Model-View-Controller (MVC) Pattern
A standard Graphical User Interface (GUI) has the following functionality:
Allows the user to enter inputs into a program.
Processes those user inputs in some way (e.g. calculations, searching, sorting,
comparing).
Presents meaningful output to the user that contains results of the processing
of the user inputs.
There are three categories of code that make up a GUI in most object-oriented programming
languages:
Presentation code: code that creates the UI components (e.g. text boxes, buttons,
and radio buttons) and lays them out on the screen (layout managers).
Event logic: code that executes when the user manipulates the interface
components (e.g. searching for an employee in an employee list when the user
clicks a "Search" button).
Classes: OOP classes that model data the application needs, such as the
Employee class that models employee records in a database.
Model-View-Controller, or MVC, is the most common
design
pattern
used to create GUIs. MVC separates the
presentation, event logic, and classes by defining these three design
components:
Model - the structure and design of data, and/or objects and
classes that represent that data.
If your application stores data in a database or structured files such
as XML (extensible markup language) or JSON (JavaScript Object Notation), then
you have a specific structure for that data (e.g. field/column names, the data
types of those fields, whether or not a field is allowed null values,
which field is the primary key, etc).
This also includes code/classes with properties or data members
and methods or functions. These classes are independent of the rest
of the components. You should be able to use the model in
any application.
The model models data, nothing else! There should be no other code/logic
in the model. For example, a class that models an Employee object
should only contain data members for employee data and methods/functions that
model employee behaviours (constructors, accessors, calculate weekly pay, etc).
The Employee class should not contain code that creates a user interface for
viewing an Employee object or code that reads/writes an employee object's data
directly to a data store.
View - displays data/output to the user, provides a means for the
user to manipulate the data, trigger operations, etc.
Views are often specific to the model they're allowing a user to manipulate
and the functions that the program contains. For example, a View that displays an
employee's complete record might not be useful in an application that allows
a user to view all the student's grades in a college course. However, a view that
simply lists the records in a database table might be useful to any part of the
application that lists records, maybe even other applications that list records
(it really depends on how modular and re-usable the view's code is).
There are often multiple views on a single screen. The view is not necessarily
the whole screen: a button is a view, a text field is a view.
A view can be a container with a search text field and button, and another view on
the same screen can be a container that lists the results of the search.
Controller - the code/logic that executes behind the scenes, it
"makes things work".
Each View is paired with a Controller; they stay in sync with each other.
The controller interprets user actions on the view, such as button clicks
or typing in a field, and if appropriate, it executes specific methods/functions
to handle those actions.
Views send user inputs to the controller, and the controller processes those
inputs. For example, when you enter a new employee's data in the Employee
Information view, then click a Submit button, the view sends the input data to the
controller, and the controller executes a specific function associated with the Submit
button (perhaps it performs data validation on the input data and then saves that new
data to a file).
The controller sends outputs back to the view so the user can see them.
For example, if there are errors in the input data, the controller sends error
messages to the view. Or, if there are no errors, the controller can insert the new
record into the data store and then retrieve a list of all the records, and send
those records to the view so they can be displayed.
An example of MVC used in an object-oriented programming
language:
Model: An Student class that models a student in a college. Students
have an id, first name, last name, and Contact information. Students
can register for courses and receive grades.
View: The user interface (UI) that allows a registrar clerk to
update the student's
personal information, select the courses the student wants
to register for, and enter grade data for transcripts.
Controller: The code that retrieves Student data from a database,
updates the Student's record in the database when the clerk enters a
grade or registers the student for a course, and displays the student's
information on the Student Information screen (a view).
MVC is often used in web applications:
Model: we might have classes/objects (depending on
the language) used to represent data objects in formats like JSON
or XML: both of these are structured with properties (JSON) or elements (XML)
that represent data fields. For example, if your web application sold
socks, then you might have different socks stored as JSON objects.
A sock object might have properties for colour, size, type, pattern, and
material. If you were using an XML file, you might have a <socs></socks>
element that contained <sock></sock> objects for each type of
sock you sold. Each <sock></sock> might have child elements for
<colour>, <size>, <type>, <pattern>, and <material>.
Views: we have views (HTML pages) for
displaying information and gathering input data (such as
forms, or pages that display information with tables and lists).
You might even have placeholders in a view for dynamic data. For
example, a heading might be defined as <h1>Welcome
<%=username%></h1>, where <%=username%> is a placeholder
that will be replaced with a user's name when they load the page.
Controller: usually we have server-side code that
handles incoming requests and routes those requests to various handlers,
which then produce responses that are sent back to the client.
There could also be client-side code to perform simple tasks like client-side
validation. For example, when a user clicks the Checkout button
on their shopping cart, the client sends a request to the server: the
server executes code that totals up the purchases and calculates taxes.
Then the server code looks up the shipping options and their costs from a database,
based on the user's location. Then the server sends back a response
with the totals and a list of shipping options to choose from.
In both scenarios, data is a big part of the application. Data can potentially
be stored in databases or database servers, or even in file formats like
JSON or XML. In the MVC design pattern, the Views are how the
user triggers data operations such as saving new or edited data, or
requesting a search for a specific value in the data store.
The controller interacts directly with the data store to save/retrieve data.
The model is the template or pattern the data takes. For example,
a user can enter some new data into an HTML form and then press the Submit button.
This triggers a request to the server, and that request is processed by the
Controller. The Controller then performs the requested operation on the data store
and sends any results back to the client via HTTP response. The result is
displayed in a view.
The idea behind MVC is that it allows you to create modular and re-usable
components. For example, you might create a UI that allows a user to
enter data for players on their fantasy hockey team. You would likely
have a Player class that models a single player. You can re-use that
Player class in several applications. You could even use the Player UI
in other applications that needed to provide a means to input/edit player
information. You can also re-use the UI in different parts of the
application: not just to input player data, but also to search for
or edit player data. By separating the event logic (validate player
input data, use data to construct a player object, save a player
object to a database, get a collection of players, get a single
player by jersey number, etc) you can use that same UI for several
different functions in the application.
Exercise
Imagine an application where you'd like to sell a specific
product (whatever you like). Think about the part of the
application that allows a customer to search for a product
by description and view the matches from your catalog.
Model: Create a UML diagram (or simply list the data members
and methods) of a class that would model an inventory
item in your catalog.
View: What user interfaces would this part of your program
require? Create rough sketches of those UIs.
Controller: What kinds of functionality is your program going to
need? Describe each function. Which functions will need
to acces the view(s)? Which functions will need to access
the Model?