Table of Contents
Le modèle architectural Model-View-Controller (MVC) est depuis longtemps la pierre angulaire du développement structuré d'applications web. En séparant une application en trois composants interconnectés – Modèle (data and business logic), Vue (interface utilisateur) et Contrôleur (programmation d'entrée) – VMC favorise le code organisé plus facile à entretenir, à tester et à étendre. Pourtant, même dans cette séparation claire, les développeurs rencontrent souvent des frictions : les données brutes du modèle de domaine correspondent rarement à la forme exacte requise par la vue, et la logique de présentation tend à s'infiltrer dans les contrôleurs ou les vues, créant ainsi un code messable, difficile à maintenir.
Qu'est-ce qu'un modèle de vue?
Un ViewModel est une classe personnalisée conçue spécifiquement pour répondre aux besoins en données et en comportement d'une vue particulière. Il se situe entre le Modèle (la couche d'accès au domaine ou aux données) et le View, transformant les données brutes en une forme que la vue peut consommer sans effort. Contrairement au modèle de domaine, qui représente les entités et les règles d'affaires (par exemple, un objet avec , , et ), un ViewModel peut contenir uniquement les champs nécessaires à cette vue—peut-être (une propriété calculée), , ou une liste de . Il aplatit également des graphiques d'objets complexes pour empêcher la vue de naviguer dans les chaînes de relations.
Considérez une page de profil d'utilisateur typique. Le modèle de domaine peut avoir des entités séparées et . Un pourrait combiner le nom d'affichage de l'utilisateur, la ville et l'état en une seule chaîne et présenter la date de jointure dans un format lisible par l'homme. Sans le modèle View, la vue devrait comprendre la structure des deux entités et effectuer la logique de formatage – une violation évidente de la séparation des préoccupations.
Modèle de vue vs. Modèle de domaine vs. DTO
Il est important de distinguer un ViewModel d'autres modèles similaires. Un objet de transfert de données (DTO) est souvent utilisé pour déplacer les données entre les couches (par exemple, d'un service à un contrôleur) et manque généralement de comportement. Un ViewModel, par contre, est spécifique aux vues et peut inclure la logique de présentation, les attributs de validation et la gestion de l'état (par exemple, est-ce que l'utilisateur est en mode d'édition?). En revanche, le modèle de domaine contient des règles d'affaires et des invariants; vous ne devriez jamais exposer les modèles de domaine directement aux vues, car cela couple votre interface utilisateur à votre couche d'affaires et peut conduire à des problèmes de sécurité et de maintenance.
Comment les modèles de vue simplifient la liaison des données
La liaison des données est le mécanisme qui relie les éléments d'interface utilisateur aux sources de données, en synchronisant automatiquement les valeurs.Dans les cadres MVC côté serveur comme ASP.NET MVC, Spring MVC ou Laravel, la liaison des données se produit généralement lors des présentations de formulaire : le cadre lit les paramètres de requête HTTP et les mapifie vers un objet modèle. Lorsque cet objet est un ViewModel, la cartographie devient simple et sécurisée.
L'utilisation d'un ViewModel pour la fixation des données offre plusieurs avantages :
- Mappage précis des champs de formulaire:[ Vous pouvez définir exactement les champs auxquels la vue s'attend, en évitant les attaques par trop-posting lorsqu'un utilisateur malveillant injecte des champs supplémentaires (par exemple, paramétrer sur un formulaire d'enregistrement).
- Les attributs de validation à caractères strongly : ViewModèles vous permettent de placer des règles de validation (comme , , ou des validateurs personnalisés) directement sur les propriétés que la vue rend. Cela centralise la logique de validation et permet une validation à la fois côté client et côté serveur.
- Erreurs de reliure réduites: Parce que le ViewModel map un à un avec le formulaire d'interface utilisateur, les développeurs évitent de deviner les paramètres de requête correspondants à des graphiques d'objets complexes.
Exemple : Formulaire d'inscription de l'utilisateur
Sans le modèle ViewModel, un contrôleur pourrait lier une requête d'enregistrement à un modèle de domaine avec des champs comme et que le formulaire ne devrait jamais définir. Avec un contenant seulement , et , le contrôleur peut lier, valider et ensuite mapper le modèle ViewModel au modèle de domaine dans la logique d'affaires.
Dans les cadres côté client qui utilisent une liaison bidirectionnelle (p. ex. Angulaire ou Vue.js), ViewModels joue un rôle similaire en définissant la forme des données que les composants afficheront et modifieront. Le ViewModel peut inclure des propriétés calculées, le suivi des changements et les gestionnaires d'événements, tous encapsulés et testables.
Rôle des modèles de vue dans la logique de présentation
La logique de présentation englobe tout ce que la vue doit faire avec les données : formatage des dates, conversion de la monnaie, concaténage des noms, calcul des totaux, décision des sections à afficher en fonction des permissions des utilisateurs, et gestion de l'état de l'interface utilisateur (par exemple, -Loading , vs. -Error , etc.). Sans ViewModèles, cette logique se retrouve souvent dans la vue (en utilisant des fonctions d'aide ou de formatage en ligne) ou dans le contrôleur (en la rendant intestable et gonflée).
Par exemple, une vue des détails de commande pourrait devoir afficher:
- Date de la commande dans un format convivial (- 15 mars 2025)
- Nom complet du client (combiné de la première et de la dernière)
- Chaque ligne comporte un sous-total (quantité × prix unitaire)
- Commandez le total avec la taxe et l'expédition
- Indique si la commande est admissible à l'annulation (selon le statut et le temps écoulé)
Toutes ces transformations appartiennent au ViewModel. La vue rend simplement des propriétés comme , , (chaque avec ), et . Le contrôleur crée le ViewModel en récupérant le modèle de domaine à partir du calque de service, en le maillant et en le passant à la vue.
Agrégation des données provenant de sources multiples
Un tableau de bord peut combiner les données du profil utilisateur, les commandes récentes et les notifications. Un ViewModel peut contenir toutes ces pièces dans un seul objet, ce qui facilite la visualisation pour rendre une page cohésive. Le contrôleur appelle des services séparés et assemble le ViewModel, qui empêche la vue de comprendre plusieurs sources de données.
Avantages de l'utilisation de ViewModels
Les avantages d'appliquer de façon cohérente le modèle ViewModel sont substantiels et ont un impact direct sur la qualité du code, la maintenance et la productivité de l'équipe.
Amélioration de la séparation des préoccupations
Les modifications apportées à l'interface utilisateur (comme l'ajout d'un nouveau champ à un formulaire) nécessitent des modifications uniquement dans le model ViewModel et non dans le modèle de domaine. Inversement, les modifications apportées au modèle de domaine (comme une nouvelle propriété sur une entité) ne se produisent pas dans la vue à moins que vous ne mettiez à jour la cartographie de ViewModel. Cette isolation réduit le risque de régression.
Amélioration de la testabilité de la logique de l'assurance-chômage
La logique de présentation dans les vues est notoirement difficile à tester. Avec ViewModels, vous pouvez tester le formatage, l'agrégation et la gestion d'état en isolation du cadre d'interface utilisateur. Vous pouvez écrire des tests unitaires qui vérifient ou sans charger un navigateur ou rendre HTML. Cela conduit à une rétroaction plus rapide et un code plus fiable.
Duplication de code réduit
Lorsque les mêmes données doivent être affichées dans plusieurs vues (par exemple, une carte produit dans une liste et dans une page de détail), vous pouvez créer une classe de ViewModel commune que les deux vues utilisent. La logique de présentation vit en un seul endroit au lieu d'être copiée dans chaque vue.
Meilleure organisation des données spécifiques à la présentation
ViewModels stocke l'état de l'interface utilisateur comme -Mode -edit, -show errors, ou -page number -. Cela maintient la vue apatride et le contrôleur concentré sur la navigation. Avec les cadres qui supportent la liaison du modèle, vous pouvez également sérialiser l'état de ViewModel sur toutes les requêtes, permettant des interactions riches comme les assistants multi-étapes.
Pièges communs et pratiques exemplaires
Même avec ses avantages, le modèle ViewModel peut être mal appliqué. Voici des erreurs courantes et comment les éviter.
Modèles de vue surchargés pour chaque vue
Pour les pages simples d'affichage qui correspondent à un seul objet de domaine, il est possible de se fixer directement à un DTO (ou même au modèle de domaine si vous utilisez un calque en lecture seule). La règle du pouce : si vous ajoutez des propriétés de formatage ou de combinaison, il faut du temps pour un modèle de vue. Utilisez le jugement – créer un modèle de vue pour chaque petite vue partielle peut gonfler la base de code.
Modèles de vue anémiques
Un modèle de vue qui n'est rien d'autre qu'un sac de propriétés publiques sans comportement peut conduire à une fuite de logique ailleurs. Inclure des méthodes d'aide ou des propriétés calculées qui encapsulent la logique de présentation (par exemple, ).
Conventions sur la désignation
Utilisez des suffixes comme (p. ex., ) ou des noms plus spécifiques comme si elle est utilisée pour la soumission de formulaire. Évitez les noms génériques comme qui obscurcissent l'intention. Organisez de façon cohérente les Modèles de vue dans un dossier distinct (p. ex., ] dans ASP.NET MVC) pour garder la structure du projet propre.
Cartographie entre domaine et modèle de vue
La cartographie manuelle (propriété par propriété) est fastidieuse et sujette aux erreurs. Utilisez un outil comme AutoMapper pour .NET, MapStruct pour Java ou les fonctions d'aide dans PHP pour automatiser la cartographie. Cependant, attention à ne pas cartographier aveuglément – parfois la structure de ViewModel diffère significativement du domaine, et la cartographie manuelle offre une clarté. Automatisez les mappages simples, mais n'hésitez pas à écrire une logique explicite pour des transformations complexes.
Mise en œuvre de modèles de vue dans les cadres
Les principes sont universels, mais les implémentations diffèrent légèrement.
ASP.NET MVC / Core
Dans ASP.NET MVC, ViewModels sont des classes C# simples placées dans un dossier . Les contrôleurs les reçoivent via des paramètres de méthode d'action utilisant des attributs ou des liaisons de modèles de vue. Les vues de rasoir sont fortement dactylographiées vers le ViewModel (. Le framework supporte les attributs de validation directement sur les propriétés de ViewModel. ViewModels sont également utilisés pour afficher les données; le contrôleur retourne . Par exemple:
public class UserProfileViewModel
{
public int Id { get; set; }
[Display(Name = "Full Name")]
public string FullName { get; set; }
public string Email { get; set; }
[DataType(DataType.Date)]
public DateTime JoinedDate { get; set; }
}
En savoir plus sur les modèles de vue dans ASP.NET Core de La documentation officielle de Microsoft.
MVC de printemps (Java)
Dans Spring MVC, ViewModels sont souvent appelés objets de support -form ou -command. - Ils sont des objets Java simples avec annotations de validation (comme , ). Le contrôleur utilise pour lier les données de formulaire au ViewModel. Pour les besoins de l'affichage, vous pouvez mettre des données dans le modèle via et ensuite les référencer dans les modèles JSP ou Thymeleaf. Spring prend également en charge ] pour les éditeurs de propriétés personnalisés.
Larave (PHP)
Laravel n'a pas de classes ViewModel intégrées mais encourage le modèle par des requêtes de formulaire (validation) et des classes de ressources (réponses API). Pour les vues rendues par le serveur, vous pouvez créer des classes personnalisées ou simplement passer un tableau. Cependant, en utilisant des classes ViewModel dédiées (par exemple ), vous améliorez la sécurité et la testabilité du type.
Modèles de vue avancés
À mesure que les applications grandissent, vous aurez peut-être besoin de structures de ViewModel plus sophistiquées.
Modèles de vue imbriquée
Lorsqu'une vue contient une liste d'éléments, créez un modèle de vue parent qui possède une collection de modèles de vue enfant. Par exemple, un peut contenir et . Chaque modèle de vue enfant a sa propre logique de présentation.
AffichageHéritage et composition du modèle
Si plusieurs vues partagent des propriétés communes (par exemple, une section -en-tête de page avec des informations utilisateur et des éléments de menu), vous pouvez créer une classe de base ViewModel et l'étendre. Sinon, utilisez la composition: incluez une comme propriété. La composition est souvent plus flexible et évite les hiérarchies d'héritage profondes.
Modèles de vue avec initialisation asynchrone
Certains modèles de vue nécessitent des données d'appels asynchrones (par exemple, des API externes). Vous pouvez créer une méthode d'usine ou un service dédié qui construit le modèle de vue asynchrone. Le contrôleur attend l'usine et transmet le résultat à la vue. Cela maintient le contrôleur synchrone et testable tout en permettant la population asynchrone du modèle de vue.
Conclusion
Les modèles de vision sont un outil puissant mais souvent sous-utilisé dans le développement de MVC. En servant d'intermédiaire sur mesure entre les modèles et les vues, ils simplifient la liaison des données, centralisent la logique de présentation et imposent une séparation nette des préoccupations. Ils protègent les modèles de domaine des changements spécifiques à l'interface utilisateur, améliorent la testabilité, réduisent la duplication et rendent la base de code plus durable à mesure que l'application évolue.
En implémentant ViewModels, n'oubliez pas de les garder maigres mais expressives, de tirer parti des attributs de validation et d'utiliser judicieusement les outils de cartographie. Évitez le piège de faire dépendre chaque vue d'un ViewModel – utilisez-les là où ils ajoutent de la valeur. La discipline de conception de ViewModels va affiner votre compréhension des besoins réels de votre UI et conduire à des applications MVC plus propres et plus robustes. Pour plus de détails, voir Martin Fowler , discussion de Model de présentation, un modèle étroitement lié à ViewModels, et l'aperçu de l'architecture Microsoft MVC pour une vue complète du modèle dans ASP.NET.