Introducting MVVM (Model-View-ViewModel) software architecture

by • Mon Jan 23 2023 00:00:00 GMT+0000 (Coordinated Universal Time)

Introducting MVVM (Model-View-ViewModel) software architecture
Back to home
csharp

Introducting MVVM (Model-View-ViewModel) software architecture


Introduction:

Presentation of MVVM software architecture pattern

MVVM, or Model-View-ViewModel, is a software architecture pattern that was introduced by Microsoft in 2005. It is commonly used in the developement of applications that use XAML, such as those for WPF, Xamarin, UWP, and Avalonia, etc. MVVM separates the user interface (UI) into three distincts components: the model, which represents the data, the view which represents the UI; and the view model, which acts as the link between both. This separation of concerns allows for better code organization, testability, and maintenability. It also respects the different principles of SOLID. That’s good, right ?

MVVM is often compared to other architecture patterns such as MVC (Model, View, Controller), MVP (Model, View, Presenter) or MVU (Model, View, Update). While all of these pattern aim to separate the concerns of the UI and the data, MVVM is particularly well-suited for use with XAML-based frameworks due to its support for data binding.

Pros and cons of using MVVM in your software project

There are several advantages to using the MVVM architecture pattern in software projects :

  • Separation of concerns: By separating the model, the view and the view model, MVVM allows developers to focus on specific areas of the code, making it easier to understand, modify, and test. This improve code organization and maintenability.

  • Testability: The seperation of concerns in MVVM makes it easier to write automated tests for each components of the application. This improves the overall quality and the robustess of the codebase.

  • Data Binding: MVVM is particularly well-suited for use with XAML-based frameworks, such as Windows, Xamarin, and UWP, because it supports data binding. This allows for a direct link between the view and the view model, making it easier to update the UI when the underlying data changes

  • Reusability: MVVM’s separation of concerns allows developers to reuse code, such as the model and view model, across different views and platforms.

  • Flexibility: MVVM allows for more flexibility in the development process. By separating the view from the view model, developers can create multiple views for the same view model, allowing for variations of the same application, for example, different views for mobile and desktop platforms.

Overall, MVVM is an architecture pattern that can bring many benefits to software projects. Its separation of concerns, testability, data binding, reusability and flexibility make it a valuable tool for developers working on XAML-based projects.

While MVVM has many advantages, there are also some potential downsides or cons to consider when using it in a software project :

  • Complexity: MVVM can add complexity to the project, especially for developers who are not familiar with the pattern. It can take some time to fully understand the relationships between the different components and how they interact.

  • Overhead: Using MVVM can add some overhead in terms of setup and configuration, especially when using a framework such as MVVMLight. This can make it more difficult to quickly prototype or make changes to the application.

  • Limited use: MVVM is primarily used for XAML-based frameworks and its use is limited to those platforms. It might not be the best fit for other types of projects or platforms.

  • Dependence on data binding: MVVM relies heavily on data binding, which can make it difficult to debug or troubleshoot issues with the application.

It’s important to keep in mind that the choice of architecture pattern should depend on the specific requirements of the project and the team’s expertise. While MVVM can bring many benefits, it’s important to weigh the cons against the specific use case and the expertise of the team.

Model-View-ViewModel, example

Model

In a basic GUI project using C#, the Model component of MVVM can be implemented as a plain old C# object (POCO) that implements the INotifyPropertyChanged (INPC) interface. This allows the view to be notified when the properties of the model change.

class PersonModel 
    : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Note: That’s a vanilla, really basic implementation of the INotifyPropertyChanged interface

View

The View component of MVVM can be implemented as a user control or window in a WPF or UWP application, or as an activity or fragment in an Android or iOS application. In this example, the view is a simple WPF window that displays a textbox and a label, bound to the “Name” property of the model.

<Window x:Class="PersonView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
        <Label Content="{Binding Name}"/>
    </StackPanel>
</Window>

View Model

The ViewModel component of MVVM acts as a link between the model and the view, and is responsible for exposing the data from the model in a way that the view can understand and display. In this example, the view model is a simple class that holds a reference to the model and exposes it to the view.

class PersonViewModel
{
    private readonly PersonModel _model;
    public PersonModel Model { get { return _model; } }
    public PersonViewModel(PersonModel model)
    {
        _model = model;
    }
}

When using MVVM Toolkit, MVVMlight, or Avalonia Reactive UI with Fody, the implementation of the INPC is simplified. Instead of having to manually implement the INPC interface and raise the PropertyChanged event, these frameworks provide a way to automatically handle the INPC through the use of attributes or by weaving the code at compile time.

MVVMLight, ObservableObject

For example, in MVVMLight, you can use the ObservableObject class as a base class for your model and the RaisePropertyChanged method to raise the PropertyChanged event.

class PersonModel 
    : ObservableObject
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            RaisePropertyChanged();
        }
    }
}

AvaloniaUI with ReactiveUI (included with Fody)

class PersonModel
    : ReactiveObject
{
    [Reactive] 
    public string Name { get; set; }
}

Pretty neat, right ?

MVVM Toolkit, with ObservableObject

In MVVM Toolkit, you can use the ObservableObject class as a base class for your view model, which already implements the INPC and other useful functionality such as commands, messaging, and more.

public class User 
    : ObservableObject
{
    private string name;

    public string Name
    {
        get => name;
        set => SetProperty(ref name, value);
    }
}

From MS docs

Each one of these frameworks provides a way to simplify the implementation of the MVVM pattern, but they also provide additional functionality such as commands, messaging, navigation, and more. It’s important to choose the one that fits better with your project needs, also, you can use more than one of them in a project.

It’s important to notice that this is a basic example, in a real-world scenario, the model, view, and view model classes would likely have more complex functionality and interact with other components of the application. Additionally, it’s important to note that the framework you choose will also depend on the type of project you are working on and the platforms you are targeting.

In conclusion, MVVM* is a powerful software architecture pattern that can bring many benefits to software projects, such as separation of concerns, testability, data binding, reusability and flexibility. It is particularly well-suited for use with XAML-based frameworks, such as Xamarin, UWP, WPF, etc.

In this article, we have explained the basic structure of MVVM, including the Model, View, and ViewModel components, and provided a basic example of how it can be implemented in a simple gui context. We also discussed the advantages and disadvantages of using MVVM, and looked at how it can be implemented using INPC and different frameworks such as MVVM Toolkit, MVVMLight, and Avalonia Reactive UI with Fody.

In the next article, we will take a deeper dive into MVVM by building a basic application using vanilla implementation of MVVM, and then compare it with the same application built using the Community Toolkit and Avalonia Reactive UI. This will allow you to see the differences and similarities between the various implementations and help you choose the best approach for your own projects.

ecrin digital Looking for a full-stack developer?

Explore Ecrin Digital, a full-stack development agency that can help you with your next project. Quality is their top priority, and they are committed to delivering the best possible product.

Discover Ecrin Digital.

Need a backend expert?