Qu’est-ce que MVVM ?

Effectué

Les applications .NET MAUI qui n’utilisent pas MVVM ont généralement davantage de code dans leurs fichiers code-behind. Les fichiers code-behind dans .NET MAUI suivent ce modèle : {quelque chose}.xaml.cs. La plupart du code dans le fichier code-behind contrôle généralement le comportement de l’interface utilisateur (IU). Le comportement de l’interface utilisateur peut inclure tout ce qui se passe dans l’interface utilisateur, comme la modification d’une couleur ou du texte. De même, il peut inclure tout ce qui se passe à cause de l’interface utilisateur, notamment les gestionnaires de clics de bouton.

Le problème avec cette approche est qu’il est difficile d’écrire des tests unitaires sur des fichiers code-behind. Les fichiers code-behind supposent souvent un état de l’application qui est créé en analysant le XAML ou même par d’autres pages. Il est difficile de gérer ces conditions dans une série de tests unitaires qui ne s’exécute peut-être même pas sur un appareil mobile, livrée à elle-même avec une interface utilisateur. Ainsi, les tests unitaires sont rarement en mesure de tester les comportements de l’interface utilisateur dans ces fichiers.

Mais c’est là que le modèle MVVM s’avère utile. Utilisé correctement, le modèle MVVM résout ces problèmes en déplaçant la majorité de la logique comportementale de l’interface utilisateur vers des classes testables dans des tests unitaires appelées modèles-vues. Le modèle MVVM est plus couramment utilisé avec des frameworks qui prennent en charge la liaison de données. En effet, avec .NET MAUI, vous pouvez lier les données de chaque élément de l’interface utilisateur à un viewmodel et éliminer, ou presque, le code dans une vue ou un code-behind.

Quelles sont les parties d’une application MVVM ?

Même si le viewmodel est la seule partie du modèle MVVM, le modèle définit également une partie modèle et une partie vue. Les définitions de ces parties sont cohérentes avec d’autres modèles courants, comme le modèle MVC (modèle-vue-contrôleur).

Qu’est-ce qu’un modèle ?

Dans une application MVVM, le terme modèle est utilisé pour désigner vos données et vos opérations métier. Le modèle ne s’implique pas lui-même dans la présentation utilisateur de l’application.

Une règle utile pour déterminer quel code appartient au modèle est qu’il doit être portable sur différentes plateformes. Depuis une application mobile vers une interface web ou même un programme de ligne de commande, en utilisant le même modèle dans toutes les instances. Il n’est pas lié à la façon dont les informations sont affichées à l’utilisateur.

Pour l’application de ressources humaines de notre scénario, le modèle peut inclure une classe Employee et une classe Department qui contiennent des données et la logique relatives à ces entités. Le modèle peut également inclure des éléments comme une classe EmployeeRepository qui contient la logique de persistance. D’autres modèles de conception de logiciels envisagent les éléments comme les référentiels de manière séparée du modèle. Mais dans le contexte de MVVM, nous nous référons souvent à la logique métier ou aux données métier dans le cadre du modèle.

Voici deux exemples de modèle en C# :

public class Employee
{
    public int Id { get; }
    public string Name { get; set; }
    public Employee Supervisor { get; set; }
    public DateTime HireDate { get; set; }
    public void ClockIn() { ... }
}

public class EmployeeRepository
{
    public IList<Employee> QueryEmployees() { ... }
    ...
}

Qu’est-ce qu’une vue ?

Le code de la vue contrôle les éléments qui interagissent directement avec l’utilisateur, tels que les contrôles comme des boutons et des champs d’entrée, ainsi que d’autres éléments purement visuels comme des thèmes, des styles et des polices.

Dans .NET MAUI, vous n’avez pas besoin d’écrire de code C# pour générer vous-même une vue. Au lieu de cela, vous définissez souvent vos vues via des fichiers XAML. Bien sûr, il existe des situations qui nécessitent un contrôle utilisateur personnalisé, dans lequel vous créez votre propre vue via du code.

Qu’est-ce qu’un viewmodel ?

Revenons maintenant au viewmodel. Le viewmodel est l’intermédiaire entre notre logique métier (le modèle) et nos vues (l’interface utilisateur).

Diagramme montrant comment une vue modèle agit comme intermédiaire entre un modèle et une vue.

Réfléchissez à ce qu’un viewmodel peut faire pour l’application RH. Supposons qu’il existe une vue qui affiche la durée des congés disponibles d’un employé, et que vous voulez que le solde des vacances s’affiche sous la forme « 2 semaines, 3 jours, 4 heures ». La logique métier du modèle fournit cependant cette même valeur sous la forme « 13,5 jours », un nombre décimal représentant le nombre total de jours pour des journées de travail de 8 heures. Le modèle objet peut se présenter comme la liste suivante :

  • Modèle – La classe Employee, qui inclut une méthode :

    public decimal GetVacationBalanceInDays()
    {
        //Some math that calculates current vacation balance
        ...
    }
    
  • ViewModel – Une classe EmployeeViewModel qui a une propriété comme celle-ci :

    public class EmployeeViewModel
    {
        private Employee _model;
    
        public string FormattedVacationBalance
        {
            get
            {
                decimal vacationBalance = _model.GetVacationBalanceInDays();
                ... // Some logic to format and return the string as "X weeks, Y days, Z hours"
            }
        }
    }
    
  • Vue – Une page XAML qui contient une seule étiquette et un bouton Fermer. L’étiquette est liée à la propriété du viewmodel :

    <Label Text="{Binding FormattedVacationBalance}" />
    

    Vous avez simplement besoin que le BindingContext de la page soit défini sur une instance de EmployeeViewModel.

Dans cet exemple, le modèle contient la logique métier. Cette logique n’est pas liée à un affichage visuel ou à un appareil. Vous pouvez utiliser la même logique pour un appareil portable ou un ordinateur de bureau. La vue ne sait rien de la logique métier. Les contrôles de la vue, comme l’étiquette, savent comment obtenir du texte à l’écran, mais ne s’occupent pas de savoir s’il s’agit d’un solde de congés ou d’une chaîne aléatoire. Le viewmodel connaissant un peu les deux univers, il peut agir en tant qu’intermédiaire.

Ce qui est intéressant, c’est la façon dont le viewmodel procède pour agir en tant qu’intermédiaire : il expose les propriétés auxquelles une vue peut être liée. Les propriétés publiques constituent la seule façon pour un viewmodel de fournir des données. Ceci nous amène à la raison pour laquelle on l’appelle viewmodel. Le « modèle » dans MVVM représente la structure, les données et la logique des processus métier. Le viewmodel représente la structure, les données et la logique dont la vue a besoin.

Comment la vue fonctionne-t-elle avec le viewmodel ?

Quand vous examinez la relation du viewmodel avec le modèle, vous voyez que c’est une relation de classe à classe standard. Le viewmodel a une instance du modèle et expose les aspects du modèle à la vue via des propriétés. Mais comment une vue obtient-elle et définit-t-elle des propriétés sur le viewmodel ? Quand le viewmodel change, comment la vue met-elle à jour les contrôles visuels avec de nouvelles valeurs ? La réponse est la liaison de données.

Les propriétés du viewmodel sont lues au moment où l’objet est lié à la vue. Cependant, la liaison n’a aucun moyen de savoir si les propriétés du viewmodel changent après que la liaison a été appliquée à la vue. Modifier le viewmodel ne propage pas automatiquement la nouvelle valeur via la liaison à la vue. Pour effectuer une mise à jour du viewmodel vers la vue, le viewmodel doit implémenter l’interface de System.ComponentModel.INotifyPropertyChanged .

L’interface INotifyPropertyChanged déclare un seul événement nommé PropertyChanged. Il prend un seul paramètre : le nom de la propriété qui a changé sa valeur. Le système de liaison utilisé dans .NET MAUI comprend cette interface et est à l’écoute de cet événement. Quand une propriété change sur le viewmodel et déclenche l’événement, la liaison notifie le changement à la cible.

Réfléchissez à la façon dont cela fonctionne dans l’application RH avec un viewmodel d’employé. Le viewmodel dispose de propriétés qui représentent un employé, comme le nom de l’employé. Le viewmodel implémente l’interface INotifyPropertyChanged et, quand la propriété Name change, il déclenche l’événement PropertyChanged, de la manière suivante :

using System.ComponentModel;

public class EmployeeViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    private Employee _model;

    public string Name
    {
        get {...}
        set
        {
            _model.Name = value;
            OnPropertyChanged(nameof(Name))
        }
    }

    protected void OnPropertyChanged(string propertyName) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

La vue qui décrit les détails de l’employé contient un contrôle d’étiquette qui est lié à la propriété Name de viewmodel :

<Label Text="{Binding Name}" />

Quand la propriété Name change dans le viewmodel, l’événement PropertyChanged est déclenché avec le nom de cette propriété. La liaison écoute l’événement, puis avertit l’étiquette que la propriété Name a changé. Ensuite, la propriété Text de l’étiquette est mise à jour avec la dernière valeur.

Contrôle de vos connaissances

1.

Un développeur travaille sur une application .NET MAUI et veut implémenter le modèle MVVM. Il a créé un modèle pour les données et les opérations métier, ainsi qu’une vue pour l’interaction utilisateur. Que doit-il ensuite créer pour agir comme intermédiaire entre le modèle et la vue ?

2.

Une équipe développe une application mobile en utilisant .NET MAUI et veut s’assurer que sa logique métier est portable sur différentes plateformes. Où doivent-ils placer cette logique métier dans le modèle MVVM ?