MVP et plusieurs contrôles utilisateur

J’essaie d’utiliser le modèle MVP et je rencontre un problème de conception. Je développe une application qui aura plusieurs UserControls. Les contrôles utilisateur eux-mêmes n’ont rien à voir les uns avec les autres et ne représentent qu’un sous-ensemble du modèle actuel. D’après ce que j’ai lu, les gens ont tendance à dire que vous devriez utiliser un présentateur par vue. Cela semble logique, mais si j’ai 30 UserControls, est-ce que je veux vraiment 30 présentateurs? D’un autre côté, si j’ai 1 présentateur et 1 vue qui représentent la vue «application» entière, alors les interfaces View et Presenter seront surchargées. Ensuite, chaque vue devra implémenter des méthodes qui n’ont rien à voir avec cela. Ma question est la suivante: existe-t-il un meilleur moyen de gérer plusieurs contrôles utilisateur ou dois-je simplement créer un présentateur pour chaque vue?

Il serait plus logique de regrouper le code associé dans un seul object. Ainsi, dans ce cas, si les vues sont des groupes spécifiques de code associé, le présentateur imitera également ces groupes. Avoir un présentateur “global” pour différentes vues regrouperait le code non lié dans un seul object. Cela risquerait également de gêner l’interface du présentateur. Découvrez le principe de responsabilité unique .

Maintenant, vous pourriez avoir une classe Presenter Manager qui pourrait peut-être vous donner access à chaque interface du présentateur, comme le stipule le principe de séparation des interfaces , par inheritance (avoir un présentateur concret global qui implémente plusieurs interfaces de présentateur … ) ou d’agrégation (avoir des présentateurs individuels pour chaque interface et obtenir des fonctions … ainsi l’interface globale serait les fonctions d’obtention) ou une combinaison des deux (le présentateur global étant un peu un adaptateur).

Je pense que la meilleure solution serait simplement d’avoir 30 présentateurs différents.

Vous devriez faire un présentateur par un contrôle à cause de:

  • cela vous permettrait d’avoir des tests unitaires ciblés qui ne traitent que le contrôle
  • facilité de maintenance accrue car vous n’avez pas besoin de supporter un présentateur gigantesque contenant l’union de la logique de présentation de tous les contrôles
  • cela éviterait la redondance en cas de contrôle identique sur plusieurs pages
  • Augmente la SRP en disposant des contrôles se concentrant sur leur logique spécifique pendant que la page remplit des rôles spécifiques au conteneur:

Deux problèmes sont généralement mentionnés, liés à la décision «présentateur par contrôle»:

  • Le contexte partagé est un problème car, du fait que tous les contrôles affichent simplement différents éléments du même contexte de données de page, cette situation peut ressembler à un cas d’utilisation problématique conduisant à beaucoup de code redondant d’extraction de données dans chaque contrôle. Cela peut être facilement résolu par une dependency injection, où page (ou le contrôleur) effectue une extraction de données unique, puis injecte l’object de contexte de données dans chacun des présentateurs \ vues (implémentant généralement une interface le permettant). Dans le cas d’un modèle MV-VM (Silverlight, WPF), le même effet peut être obtenu via une délimitation des données, la page définissant son DataContext qui sera ensuite utilisé à partir de vues
  • La communication entre les vues sur la même page est le deuxième problème qui peut être facilement résolu en utilisant plusieurs approches:
  • Les contrôles publient des événements auxquels la page est abonnée, puis appelle directement les méthodes appropriées dans d’autres contrôles (la page contient tous les contrôles, ce qui signifie qu’elle est consciente de tous leurs membres).
  • Modèle de conception de l’ observateur
  • Modèle d’ agrégateur d’événements

Dans chacune de ces approches, les contrôles communiquent entre eux sans se connaître

Chaque vue n’a pas à implémenter la même interface … Pourquoi ne pas définir les interfaces de chaque contrôle et avoir un présentateur pour l’écran complet contenant tous les contrôles? Le présentateur peut “relier” les événements de chaque vue en fonction de l’interface requirejse par chaque vue, aux gestionnaires d’événements appropriés sur le présentateur (et sur un contrôleur si vous exécutez MVPC). Vous aurez peut-être également besoin d’une autre interface pour représenter la fonctionnalité de présentateur à laquelle toutes les vues ont besoin d’accéder en commun …

  • Si vous utilisez MVPC, les événements qui affectent le modèle doivent être “gérés” dans le contrôleur, alors que les événements qui affectent uniquement d’autres parties de la vue seront gérés par le présentateur.

Vieille question, mais je vais me mettre au courant et être en désaccord avec les autres réponses: vous ne voulez pas d’un présentateur par UserControl, pas plus que vous ne voulez un test unitaire sur chaque UserControl – ce serait un abus aveugle d’un design pattern.

Un UserControl n’est pas une vue.

Chaque zone logique de votre application doit avoir un présentateur. la façon dont chacun est divisé – combien de contrôles, ce qui montre quoi – est uniquement un problème de composition .