§10.9.

Model view controller (MVC) architecture

The model view controller architectural pattern is used in presentation logic to separate state (the model), layout (the view) and behavior (the controller).

Related concepts are model view view-model (MVVM) and model view presenter (MVP).

Problem

The presentation layer must do several things at once:

  • Show the user interface on the screen: not only functional components but also images and labels of a visually appealing user interface

  • Accept user input and handle user actions, perhaps with animations and other attractive transitions

  • Process the user input, translating the actions into the domain layer

  • Translate the domain layer responses back into feedback on the user interface

When user interfaces grow in complexity, the presentation layer code may become unmanageably complex. For example, the React code in src/ui/ShoppingList.jsx of the React team shopping list already has over 150 lines of code even though it is simple and unattractive. [1] Separating the shopping list component into sub-components (e.g., list viewer, list item and a new item creator) will spread these lines of code over smaller and more manageable files. However, the complexity arising from the combination of tasks that each component performs will continue growing.

Exercise: Modularizing the front-end

How would you separate the front-end code into multiple sub-components? (you can use either the React or Angular projects)

Spend thirty minutes or more, making the user interface more modular. Are you happy with your modular code? What problems do you see with it?

Solution

The model view controller architecture (MVC) is one of the oldest architectures for graphical user interfaces. [2] The idea of MVC is to separate the user interface into three responsibilities:

  • Model: Responsible for storing the underlying data and handling update commands on the data (i.e., the model holds the data shown in the component)

  • View: Responsible for translating the data in the model into a visual representation (i.e., the view makes the component ‘attractive’)

  • Controller: Responsible for validating and translating user inputs into update commands for the model (i.e., the controller handles the behavior)

These three components work together to handle user input. The controller accepts input, updates the model, which the view renders for the user:

User-Controller-Model-View-User Cycle

In practice, these responsibilities are imprecise guidelines. The MVC architecture comes from desktop graphical user interfaces where these responsibilities are sharply delineated. [3] On the web, the differences between the responsibilities are less precise. Still, the fundamental principle of MVC remains: as far as possible separate the visual layout, the input processing and the underlying manipulation from each other.

The terms model view view-model (MVVM) and model view presenter (MVP) are related approaches for separating responsibilities in a user interface. In MVVM, the framework provides a single system controller for all pages. The view-model provides a simplified mapping of the model. The view-model is used by both the view and the system controller. In MVP, a presenter replaces the controller. Rather than the controller performing a one-way update of the model based on user input in MVC, the presenter performs a two-way translation from user input into the model and then an appropriate update on the view.

Implementation

Both Angular and React support MVC architectures. They make it easy to separate responsibilities in the presentation layer.

MVC in Angular

Several features in Angular directly map onto MVC concepts:

  • The ng generate component command generates a TypeScript file for handling user input (i.e., the controller) and an HTML template file to create a visual layout (i.e., the view)

  • The ng generate service command creates a separate TypeScript file that is independent of any component. Non-graphical application logic belongs in services (i.e., the model).

Applying the principles of MVC in Angular requires consideration of the purpose of any given code. Identify the responsibility of each line of code and then place that code into the appropriate files:

  • Place the layout, presentation, styling and visual logic in the template files.

  • Embed user input handling into the component’s controller.

  • Place code that does not directly reference to a user interface component in service files (e.g., code that handles communication with a web API).

MVC in React

React does not provide a recommended structure for MVC code. Instead, it provides a general-purpose framework to assist in developing MVC applications.

Some strategies to improve the separation of responsibilities in React code include:

  • Extracting code into separate files (e.g., moving code that communicates with a web API into a ‘service’ or ‘helper’ module)

  • Ensuring that render() remains a simple function that only produces HTML

  • Separating event handling callbacks from component state update in separate sections of the same file, or in distinct files

  • Using sub-components to handle the UI’s visual features, and higher-level parent components to act as controllers

  • Implementing the visual sub-components as React Function Components: components that only return a JSX, but do not have any internal state

One popular approach to applying MVC principles to React is the use of Redux. Redux uses a store and reducers that together provide a systematic way of implementing the model of MVC. The introduction of Redux into a project will increase the initial complexity. However, Redux helps isolate the behavior and state of the presentation layer from the purely visual responsibilities of the presentation layer. This additional isolation ensures a more maintainable system, by reducing complexity in the long-run.

It helps to be familiar with both Angular and React. Good React code is similar to an Angular project. Conversely, it helps to draw inspiration from React when writing good Angular code.

Exercise: Apply MVC

Redesign either the React or Angular (or both!) team shopping list applications so that the responsibilities for view, control and model are separate.

Is the resulting code more clear?

Reflection: Benefits and weaknesses

What challenges arose when you applied the MVC architecture to the team shopping list?

In what situations is MVC most useful? When would it not be useful?


1. The same problem occurs, to a lesser extent, in the code in src/ui/shopping/team-shopping-list.component.ts of the Angular team shopping list.
2. MVC originated in the Smalltalk systems under development at Xerox PARC research center. Xerox PARC pioneered many ideas of modern Graphical User Interfaces.
3. This clear delineation occurs because desktop applications create view components directly through a user interface library. In contrast, the web browser renders the view as a result of a complex interaction of technologies: HTML, JavaScript and CSS running on both the server and the client.