MVVM: Model-View-ViewModel o ‘Madonna Voglio Vivere Meglio’?

Reading Time: 4 minutes

Ammettiamolo, il mondo dello sviluppo software è pieno di sigle che sembrano l’acronimo di un’organizzazione segreta (e a volte lo sono, sigh). Oggi mettiamo sotto la lente una delle più chiacchierate: MVVM.

Non si tratta di un mantra per una vita più zen (anche se, diciamocelo, un’architettura pulita aiuta eccome a vivere meglio!), ma del pattern Model-View-ViewModel. E no, non è una roba per nostalgici di Madonna (anche se, a pensarci bene, la sua capacità di reinventarsi ci sta).

MVVM è un modello architetturale che, come un abito sartoriale, è stato cucito su misura da Microsoft per le applicazioni che utilizzano tecnologie di data-binding dichiarativo, come WPF e Silverlight, e che oggi è onnipresente in Xamarin, .NET MAUI e in generale nello sviluppo C# moderno. Il suo scopo? Separare in modo netto l’interfaccia utente (UI) dalla logica di business e dai dati.Immagine di MVVM Model-View-ViewModel architecture diagram


La Trinità del codice pulito: model, view, viewmodel

Il pattern si compone di tre elementi fondamentali, ognuno con un ruolo ben definito:

  1. Model (M):
    • È il cuore pulsante dei dati e della logica di business. Contiene le classi che rappresentano la struttura dei dati (ad esempio, un oggetto Prodotto o Utente) e la logica per la loro manipolazione (accesso al database, calcoli, validazioni).
    • È completamente ignaro dell’esistenza della View e del ViewModel.
    • Quando i dati del Model cambiano, in genere notifica il ViewModel.
  2. View (V):
    • È l’interfaccia utente, ciò che l’utente vede e con cui interagisce. In C# e WPF/MAUI, è spesso definita in XAML.
    • Il suo unico compito è visualizzare i dati forniti dal ViewModel e catturare gli input dell’utente (click, digitazione).
    • È una classe stupida o passiva: non contiene logica di business o manipolazione diretta dei dati. Tutta la sua intelligenza deriva dal data-binding al ViewModel.
  3. ViewModel (VM):
    • È il mediatore, l’astrazione della View. È la vera star del pattern.
    • Espone dati (sotto forma di proprietà) e comandi (sotto forma di ICommand) che la View può bindare.
    • Riceve le richieste dalla View, si interfaccia con il Model per ottenere/aggiornare i dati e notifica la View dei cambiamenti, in modo che l’UI si aggiorni automaticamente (grazie a interfacce come INotifyPropertyChanged).
    • Non ha alcuna dipendenza dalla View, il che lo rende incredibilmente facile da testare!

MVVM in C#: proprietà e binding

Il vero trucco di MVVM, in C# con framework come WPF o MAUI, è il Data Binding dichiarato in XAML, che sincronizza automaticamente la View e il ViewModel.

1. Il ViewModel e INotifyPropertyChanged

Per far sì che le modifiche nel ViewModel vengano riflesse nella View, le proprietà devono notificare il cambiamento. Ecco lo snippet essenziale, spesso implementato in una classe base per tutti i ViewModel:

C#

using System.ComponentModel;
using System.Runtime.CompilerServices;

public abstract class BaseViewModel : INotifyPropertyChanged
{
    // L'evento magico che notifica i cambiamenti alla View.
    public event PropertyChangedEventHandler PropertyChanged;

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

    // Un helper per semplificare l'impostazione delle proprietà
    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Equals(storage, value))
        {
            return false;
        }

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

public class MioViewModel : BaseViewModel
{
    private string _messaggioDiBenvenuto = "Ciao ShareTime!";

    public string MessaggioDiBenvenuto
    {
        get => _messaggioDiBenvenuto;
        set => SetProperty(ref _messaggioDiBenvenuto, value); // Usa l'helper per notificare
    }
    
    // Altri dati, comandi...
}

2. La View e il data binding

Nella View (XAML), colleghiamo un elemento UI direttamente alla proprietà del ViewModel usando la sintassi {Binding}.

XML

<StackPanel>
    <Label Content="{Binding MessaggioDiBenvenuto}" FontSize="24"/>
    <TextBox Text="{Binding MessaggioDiBenvenuto, Mode=TwoWay}"/>
</StackPanel>

Il Mode=TwoWay nel TextBox assicura che non solo il ViewModel aggiorni la View, ma che anche l’input dell’utente nella TextBox aggiorni la proprietà MessaggioDiBenvenuto nel ViewModel. Nessun code-behind necessario!


ICommand: quando la view deve fare qualcosa

MVVM non si limita a esporre dati; deve anche esporre le azioni che l’utente può compiere. Lo fa tramite l’interfaccia ICommand. Invece di usare un event handler nel code-behind della View, si usa un ICommand nel ViewModel.

C#

using System.Windows.Input; // O equivalente specifico del framework

public class MioViewModel : BaseViewModel
{
    public ICommand AggiornaMessaggioCommand { get; }

    public MioViewModel()
    {
        // RelayCommand è una classe helper comune che implementa ICommand
        AggiornaMessaggioCommand = new RelayCommand(EseguiAggiornamento);
    }

    private void EseguiAggiornamento(object parameter)
    {
        MessaggioDiBenvenuto = "Il messaggio è stato aggiornato!";
    }
    // ...
}

E in XAML, si collega il bottone al comando:

XML

<Button Content="Aggiorna" Command="{Binding AggiornaMessaggioCommand}"/>

In questo modo, la View si limita a dire: “Ehi ViewModel, esegui il comando AggiornaMessaggioCommand!”, mantenendo la sua promessa di essere dumb (nel senso buono!).


I Vantaggi di un ‘Vivere Meglio’ Architetturale

MVVM non è un capriccio, ma una necessità in progetti complessi. I suoi benefici sono enormi:

  • Testabilità Superiore: Possiamo fare unit test sul 100% della logica di presentazione (il ViewModel) senza dover lanciare l’UI. Questo riduce bug e aumenta la fiducia nel codice.
  • Separazione delle Preoccupazioni: Logica, presentazione e dati sono separati. Gli sviluppatori possono lavorare sui ViewModel, i designer sull’XAML (View), e i backendisti sul Model, riducendo i conflitti.
  • Manutenibilità e Riutilizzo: Un ViewModel che gestisce, ad esempio, i dati di un utente, può essere riutilizzato in diverse View (su desktop, mobile, tablet), semplicemente cambiando l’aspetto visivo (la View).

Certo, MVVM non è la risposta a tutto. Per le applicazioni “Hello World” o le interfacce utente estremamente semplici, può essere un overkill, introducendo codice extra. Ma non appena il progetto prende forma e la logica di presentazione diventa complessa, MVVM è il salvagente che ci permette di “Vivere Meglio” il nostro codice!

In conclusione, che tu lo chiami Model-View-ViewModel o lo pensi come un augurio di chiarezza nel codice, MVVM è una delle skill fondamentali per chiunque lavori con C# e GUI. Inizia ad applicarlo e sentirai la differenza nella tua prossima release!


Il video “What is MVVM (Model-View-ViewModel) Pattern?” fornisce un’introduzione visiva e pratica a come implementare il pattern MVVM e come si collega a concetti in C# come ObservableCollection e l’uso di Code-Behind.

Se questo articolo ti è piaciuto condividilo
Torna in alto