Mastering MVVM With Swift

How Does the Model-View-ViewModel Pattern Work

In this episode, we take a closer look at the internals of the Model-View-ViewModel pattern. We explore what MVVM is and how it works.

Remember from the previous episode that the Model-View-ViewModel pattern consists of four components or layers:

  • Model
  • View
  • View Model
  • and Controller

The Model-View-ViewModel Pattern in a Nutshell

Keep this diagram in mind. Let's start by taking a look at the advantages MVVM has over MVC. Why would you even consider trading the Model-View-Controller pattern for the Model-View-ViewModel pattern?

Advantages of the Model-View-ViewModel Pattern

We already know that the Model-View-Controller pattern has a few flaws. With that in mind, what are the advantages MVVM has over MVC?

Better Separation of Concerns

Let me start by asking you a simple question. What do you do with code that doesn't fit or belong in the view and model layers? Do you put it in the controller layer? Don't feel guilty, though. That is what most developers do. The problem is that it inevitably leads to fat controllers that are difficult to manage and test.

The Model-View-ViewModel pattern offers a better separation of concerns by adding view models to the mix. The view model translates the data of the model layer into something the view layer can use. The controller layer is no longer responsible for that task.

Improved Testability

View (iOS/tvOS) and window (macOS) controllers are notoriously hard to test because of their close relation to the view layer. By migrating some responsibilities, such as data management and manipulation, to the view model, testing becomes much easier. In fact, testing view models is surprisingly simple.

Because a view model doesn't have a reference to the controller that owns it, it is straightforward to write unit tests for a view model. Another benefit of the MVVM pattern is improved testability of controllers. Controllers no longer interact with the model layer, which makes them easier to test.

Transparent Communication

The responsibilities of the controller are reduced to controlling the interaction between the view and model layers. The view model provides a transparent interface to the controller, which it uses to populate the view layer and interact with the model layer. This results in a transparent communication between the four components or layers of your application.

Basic Rules

Before we start implementing the Model-View-ViewModel pattern in an application, I would like to highlight six key elements that define the Model-View-ViewModel pattern. I sometimes refer to these as rules. But once you understand how the Model-View-ViewModel pattern does its magic, it is fine to bend or break some of these rules.

Rule #1

First, the view or window doesn't know about the controller it is owned by. Remember that views and windows are supposed to be dumb objects. They only know how to present data to the user. This is a rule you should never break. Ever.

The view doesn't know about the view controller it's owned by.

Rule #2

Second, the view or window controller doesn't know about the model. This is something that separates MVC from MVVM.

The view controller doesn't know about the model.

Rule #3

The model doesn't know about the view model it is owned by. This is another rule that should never be broken. The model should have no clue who it is owned by.

The model doesn't know about the view model it's owned by.

Rule #4

The view model owns the model. In a Model-View-Controller application, the model is usually owned by the view or window controller.

The view model owns the model.

Rule #5

The view or window controller owns the view or window. This relationship remains unchanged.

The view controller owns the view.

Rule #6

And finally, the controller owns the view model. It interacts with the model layer through one or more view models.

The controller owns the view model.

It Is Time to Refactor

You now know enough about the Model-View-ViewModel pattern to use it in a project. In the remainder of this series, we refactor an existing application. The application is powered by the Model-View-Controller pattern and we refactor it in such as way that it uses the Model-View-ViewModel pattern instead. Let's get started.

Next Episode "Meet Cloudy"