Existe-t-il un besoin d'une classe d'usine pour créer des modèles d'affichage?

17

Un de mes collègues a suggéré d'utiliser une classe d'usine pour créer des objets Viewmodel dans nos solutions ASP.NET MVC. L'idée étant qu'elle peut aider à la conception et à la maintenabilité de la façon dont les modèles de vue sont construits dans nos applications.

Je voulais savoir si quelqu'un d'autre en avait fait l'expérience. J'ai fait quelques recherches et trouvé très peu sur cette pratique.

Actuellement, nous créons des objets viewmodel au niveau du contrôleur, par exemple

public ActionResult Index()
{
    return this.View(this.BuildIndexViewModel());
}

Donc, this.BuildIndexViewModel () est responsable de la création de la classe viewmodel (évidemment :). Mais nous étudions la possibilité de:

public ActionResult Index()
{
    return this.View(ViewModelFactory.CreateIndexViewModel());
}

C'est une idée intéressante, mais je ne suis pas convaincu à 100%. J'étais intéressé par les opinions des autres à ce sujet.

Jason Evans
la source
4
J'ai du mal à voir l'avantage pour être honnête. Vous utiliseriez une usine pour cacher la construction d'objets, mais pourquoi le feriez-vous dans ce cas?
CodeART
3
Votre méthode BuildIndexViewModel est déjà une méthode d'usine, qui est probablement privée pour le contrôleur. La seule raison d'extraire cela dans une classe d'usine distincte serait de le réutiliser dans un autre contrôleur.
MattDavey
Vous partagez tous les deux les mêmes réflexions que moi à ce sujet, donc je suis heureux de ne pas être seul :) @MattDavey Je peux honnêtement dire que je doute beaucoup que les modèles de visualisation soient utilisés avec plus d'un contrôleur, ce qui fait que l'usine idée redondante. Je partagerai cela lorsque le sujet reviendra au travail.
Jason Evans
Personnellement, je préférerais que le type de viewmodel soit l'expert du processus de construction lui-même. Le seul moment où l'expertise devrait se trouver ailleurs est si la construction nécessite la connaissance d'autres domaines d'application (par exemple les référentiels), auquel cas vous voudrez peut - être qu'un intermédiaire garde le modèle de vue muet :)
MattDavey
@MattDavey: Pouvez-vous encapsuler ces deux commentaires dans une réponse que je peux voter positivement?
pdr

Réponses:

8

Dans ce cas, je dirais que la meilleure orientation à suivre serait les principes GRASP . Regardez en particulier les quatre critères d'attribution de la création d'objet:

En général, une classe B devrait être responsable de la création d'instances de classe A si l'un, ou de préférence plusieurs, des éléments suivants s'appliquent

  • Les instances de B contiennent ou agrègent de façon composite les instances de A
  • Les instances de B enregistrent les instances de A
  • Les instances de B utilisent étroitement les instances de A
  • Les instances de B ont les informations d'initialisation pour les instances de A et les transmettent lors de la création.

Votre classe de contrôleur (B) correspond aux éléments # 3 & # 4 de cette liste (et # 2 si le viewmodel est POSTé en arrière), donc c'est déjà un endroit très sensé pour le comportement de construction du viewmodel (A). Selon moi, il n'y aurait que deux raisons qui m'obligeraient à extraire ce comportement de construction dans une classe spécialisée.

  • DRY - Si deux contrôleurs ou plus doivent partager le comportement de construction du modèle de vue, l'encapsuler dans un composant distinct faciliterait la réutilisation du code et éviterait la duplication.
  • Si le comportement de construction a des dépendances sur d'autres composants du système tels que les référentiels, les validateurs, etc., et que vous ne voulez pas introduire ce couplage au contrôleur lui-même (en termes GRASP, une pure fabrication).

En repensant à ces 4 critères de création d'objets dans GRASP, je n'extrais le comportement à une usine distincte que si cela me faisait gagner un tick supplémentaire sur cette liste. Sinon, cela n'aurait aucune valeur.

J'espère que cela pourra aider!

MattDavey
la source