Robert Martin dit: "Il ne devrait jamais y avoir plus d'une raison pour qu'une classe change".
Considérons la classe ViewModel qui est liée à une vue. Il est possible (ou même probable) que ViewModel se compose de propriétés qui ne sont pas vraiment liées entre elles. Pour les petites vues, le ViewModel peut être assez cohérent, mais pendant que l'application devient plus complexe, ViewModel exposera les données qui seront sujettes à changement pour des raisons différentes et sans rapport.
Devrions-nous nous préoccuper du principe SRP dans le cas de la classe ViewModel ou non?Comment construire le ViewModel dans MVVM pour ne pas violer le principe de responsabilité unique?
Comment construire le ViewModel dans MVVM pour ne pas violer le principe de responsabilité unique?
Répondre
La seule responsabilité de ViewModel est de fournir à View les informations dont il a besoin. Si la vue a besoin de propriétés différentes et non liées, cela n'a pas d'importance car ViewModel n'a qu'une seule raison de changer: la vue affiche des propriétés différentes. Donc vous ne devriez pas trop vous inquiéter. Cela dit, si le ViewModel devient énorme, peut-être que vous pourriez penser à diviser la vue en plusieurs sous-vues pour améliorer la réutilisabilité et maintenir les Views et les ViewModels gérables.
Oui, mais cela ne veut pas dire que la conception médiocre ne pourrait pas vous forcer.
Je suis d'accord avec gcores. Une fois que vous voyez ViewModel atteindre plus de deux écrans de texte, il est temps d'envisager de diviser ViewModel en plusieurs modèles enfants. Une autre règle empirique est que je n'ai jamais plus de deux niveaux d'imbrication dans le fichier XAML - si une partie de la vue devient trop complexe, il est temps de refactoriser la vue - extraire XAML interne dans UserControl séparé et créer ViewModel correspondant, qui sera le contexte de données par défaut dans la vue enfant.
Je suis d'accord que la division de vos écrans en plusieurs vues avec plusieurs ViewModels est nécessaire pour réduire la météorisation et la complexité. Voici un autre modèle que j'ai utilisé pour coller à SRP en utilisant MVVM:
Voici un scénario. Mon ViewModel doit obtenir des données et répondre aux commandes de filtrage de l'interface utilisateur. Je crée le ViewModel pour être composite dans la structure. Autrement dit, les classes enfants qui ont accès aux membres privés du ViewModel effectuent des tâches linéaires telles que la gestion du filtrage. Je pourrais également avoir une autre classe d'enfant qui exécute la logique nécessaire pour la sélection d'articles basés sur des critères. Vous avez eu l'idée. Une fois que le ViewModel exécute certaines fonctions couvrant plusieurs méthodes, il peut être utile de le déléguer à une classe enfant. Les classes enfant font toujours partie du ViewModel principal, ce qui permet de réduire la taille du ViewModel et facilite le test unitaire de ces opérations linéaires.