web-dev-qa-db-fra.com

La logique de tri doit-elle être placée dans le modèle, la vue ou le contrôleur?

J'ai une liste déroulante qui affiche les valeurs d'une table à l'utilisateur final. J'aimerais que ces valeurs soient triées par ordre alphabétique.

Selon une conception MVC appropriée, à quelle couche dois-je placer ma logique de tri: le modèle, la vue ou le contrôleur?

EDIT : En réponse à la question de LarsH, "Voulez-vous dire du code qui détermine quel ordre de tri est souhaité? ou du code qui effectue le tri?", j'étais à l'origine se référant au code qui détermine l'ordre de tri souhaité.

156
Ryan Kohn

(Remarque: cette citation et citation est tirée de @ réponse de dasblinkenlight , mais nous ne sommes pas d'accord sur notre interprétation. Lisez son article et faites-vous votre propre opinion).

Selon description MVC ,

Un contrôleur peut envoyer des commandes à sa vue associée pour modifier la présentation de la vue du modèle (par exemple, en faisant défiler un document). Il peut envoyer des commandes au modèle pour mettre à jour l'état du modèle (par exemple, modifier un document).

La logique de tri (par exemple, le comparateur de tri/algorithme de tri) appartient au modèle car il contient des règles métier et des données d'état. Étant donné que la modification de la façon dont les données du modèle sont triées tombe carrément dans la catégorie "modifier la présentation de la vue du modèle", le contrôleur est responsable de "faire le tri" en appelant la méthode model.changeSortedState ().

47
KyleM

Qui contrôle l'ordre de tri?

Simple MVC diagram (De Wikipedia )

1) Ordre naturel dans les données elles-mêmes:

La commande fait partie du modèle, elle devrait donc y aller. Une extraction brute de "toutes les données" retournerait les données dans l'ordre trié, et il n'y a pas d'interface pour choisir l'ordre de tri.

2) L'utilisateur doit contrôler la façon dont il voit les données:

La vue fournirait une interface (telle que des flèches ascendantes/descendantes) qui interagit avec le contrôleur, et le modèle comprend suffisamment les données pour effectuer le tri demandé sur les données. Cependant, une extraction brute des données ne doit pas nécessairement être triée, contrairement à (1).

Dans tous les cas,

La vue ne comprend pas qu'il y a un tri en cours, autre que la possibilité d'afficher la direction de tri qui a été choisie. N'y mettez pas la logique.

Petite mise en garde

La fonctionnalité de tri pourrait aller purement dans la vue, dans une circonstance (à laquelle je peux penser de manière désinvolte; il peut y en avoir plus):

Un tri "stupide" où toutes les données sont déjà dans la vue et il ne doit utiliser aucune connaissance de domaine pour effectuer le tri. Comparaison très simple de chaînes ou de nombres, par exemple. Cela n'est pas possible, par exemple, dans les résultats de recherche sur une page Web lorsque les résultats sont susceptibles d'être répartis sur plusieurs pages.

62
Izkata

Selon description MVC ,

Un contrôleur peut envoyer des commandes à sa vue associée pour modifier la présentation de la vue du modèle (par exemple, en faisant défiler un document). Il peut envoyer des commandes au modèle pour mettre à jour l'état du modèle (par exemple, modifier un document).

Selon cela, la logique de tri appartient au contrôleur, car la modification de la façon dont les données du modèle sont triées tombe carrément dans la catégorie "changer la présentation de la vue du modèle".

EDIT: Pour clarifier plusieurs malentendus exprimés dans les commentaires, la "logique de tri" n'est pas le code qui effectue le tri; c'est le code qui définit le tri. La logique de tri compare les articles individuels les uns aux autres pour établir une commande (par exemple via une instance de IComparator<T>) ou contient une logique qui construit un objet à utiliser pour la commande par un système externe (par exemple via une instance de IOrderedQueryable<T>). Cette logique appartient à votre contrôleur, car elle a besoin de connaissances liées au côté "métier" de votre application. Il est tout à fait suffisant pour effectuer le tri, mais il est distinct du code qui en fait effectue. Le code qui trie peut être dans votre vue, dans votre modèle, ou même dans la couche de persistance qui soutient votre modèle (par exemple votre base de données SQL).

18
dasblinkenlight

Aucune des réponses ci-dessus. Le tri est une logique métier, et la logique métier n'appartient à aucun des trois. Chaque élément de code de votre application ne sera pas un modèle, une vue ou un contrôleur.

Ce que je fais généralement dans mes applications MVC, c'est que j'ai une couche de service qui exécute toute la logique métier. Les méthodes de la couche service doivent avoir une API simple et propre avec des paramètres bien nommés. Vous pouvez ensuite appeler ces méthodes depuis votre contrôleur pour manipuler les données dans les modèles.

En ce sens, le tri est "dans le contrôleur", mais le code lui-même qui effectue le tri ne doit pas être implémenté dans le contrôleur, uniquement appelé à partir de là.

10
nont

Certainement pas le contrôleur: il envoie des messages pour visualiser et modéliser mais devrait faire le moins de travail possible. Si l'utilisateur peut modifier le tri, cette demande est traitée par le contrôleur en informant le modèle ou la vue à ce sujet.

Peut-être que la vue est une pure vue. Si l'application fonctionne aussi bien sans tri, alors le tri n'est qu'une partie de la représentation et devrait aller dans la vue.

Si l'ordre est inhérent au domaine, il doit aller dans le modèle.

8
Jens Schauder
  • Les vues sont la partie de MVC qui est censée contenir la logique de présentation.
  • La couche modèle est l'endroit où la logique métier est contenue.
  • Les contrôleurs modifient uniquement l'état des deux, en fonction de l'entrée utilisateur.

Donc, le choix est - pensez-vous que cela fait partie de la logique métier du domaine ou de la logique de présentation.

Si vous implémentiez un modèle MVC2 ou un modèle MVC classique approprié, je dirais que l'ordre des données fournies par la couche modèle devrait être déclenché par la demande de la vue à la couche modèle. La vue demande les données ordonnées, la couche modèle les fournit.

Mais, puisque vous utilisez l'interprétation ASP.NET MVC du modèle MVC, qui est un peu différent de votre MVC standard - l'instance ViewModel doit demander des informations ordonnées à la couche modèle (pour une raison quelconque, le framework ASP.NET pense que les modèles doivent être appelés "vues" et les vues doivent être appelées "modèles de vue" .. c'est étrange).

7
tereško

Je le fais habituellement dans le contrôleur pour rester en ligne avec le modèle selon les autres réponses. Voir ci-dessous pour le raisonnement.

J'ai réfléchi à cela et lu les réponses et le matériel connexe et, pour parler de façon pragmatique, je dirais que cela dépendrait de votre application, par exemple:

S'agit-il d'une application moyenne/grande et/ou plusieurs interfaces utilisateur y sont associées (c'est-à-dire une application Windows, une interface Web et une interface téléphonique).

  • Dans ce cas, je construirais probablement une couche de service et la mettrais dans l'objet métier, puis j'appellerais la méthode appropriée à partir du contrôleur.

S'il s'agit d'un site Web d'interface utilisateur unique bien défini et que vous utilisez quelque chose comme EF Code First et que vous n'avez pas ou n'avez pas l'intention de créer une couche de service et que vous prévoyez d'utiliser une simple méthode d'extension prête à l'emploi pour l'atteindre:

  • Dans ce cas, je l'aurais probablement mis dans le contrôleur car, de manière pragmatique, c'est le meilleur ajustement en termes de temps/budget.

Si c'est la même chose que ci-dessus, MAIS ne peut pas être implémenté avec une méthode d'extension prête à l'emploi.

  • Je peux bien choisir de le faire apparaître dans la classe Model (si c'est vraiment sur mesure pour ce type unique) car il serait plus approprié ici que dans un contrôleur. Si le tri pouvait être appliqué à plusieurs classes, je l'implémenterais dans une méthode d'extension et l'appellerais ensuite dans le contrôleur.

Pour résumer:

Réponse dogmatique: couche de service

Réponse pragmatique: généralement le contrôleur

5
bUKaneer

Je suggérerais de trier les données d'une table - les données qui sont assez petites pour être utiles dans une liste déroulante - devraient provenir de la base de données déjà triée via la requête. Pour moi, cela fait du modèle l'endroit où le tri est appliqué.

Si vous êtes déterminé à faire le tri à la main, je pense qu'il y a de bons arguments pour utiliser le modèle ou le contrôleur comme endroit préféré pour la logique. La limitation serait votre cadre particulier. Je préfère gérer les données uniquement dans le modèle. J'utilise le contrôleur pour marier les données (modèle) et la présentation (vue) comme j'ai été (auto) enseigné.

3
B0nk3r

Bien que je sois d'accord en principe avec l'idée que le tri est une logique commerciale, car en le décomposant en son origine, vous vous retrouvez avec quelque chose comme "Le client souhaite que la page du produit s'affiche avec les images triées par date", il devient alors clair que l'ordre de tri des données n'est généralement pas arbitraire - même s'il n'y a pas de tri car c'est toujours une décision commerciale par omission (une liste vide est toujours une liste).

MAIS ... Ces réponses ne semblent pas prendre en compte les progrès de la technologie ORM, je ne peux parler que par rapport à l'Entity Framework (évitons un argument pour savoir si c'est vrai ORM, ce n'est pas le point) de Microsoft comme c'est ce que j'utilise, mais je suis sûr que d'autres ORM offrent des fonctionnalités similaires.

Si je crée une vue fortement typée pour une classe de produits à l'aide de MS MVC et d'Entity Framework et qu'il existe une relation de clé étrangère entre le produit et la table d'images (par exemple FK_Product_Image_ProductId), je serais prêt à trier rapidement les images lors de leur affichage en utilisant quelque chose comme ceci dans la vue:

@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }

Il a été fait mention d'une couche Business Logic spécifique, que j'utilise également pour exécuter 80% de ma logique métier, mais je ne vais pas écrire de fonctionnalité de tri dans ma couche Business Logic qui imite quelque chose qui sort de la boîte depuis Entity Framework.

Je ne pense pas qu'il y ait une bonne réponse à cette question, à part le dire; vous devez faire abstraction de la logique métier complexe lorsque cela est possible mais pas au prix de réinventer la roue.

2
Rob

Supposons que vous ayez un site Web MVC, un site Web WebForms et une application mobile.

Si vous souhaitez que le tri soit cohérent entre ces couches de présentation, je dirais que le tri est en dehors de la couche de présentation. Le service serait un bon candidat.

Sinon, je stockerais cette logique dans un modèle de vue. Pourquoi? Parce que ce sera réutilisable et facilement testable.

1
user338195

Sur les trois que vous avez énumérés, je dirais qu'il appartient au contrôleur. Je n'aime pas vraiment placer ce genre de logique dans le contrôleur. Je crée généralement une couche de service avec laquelle le contrôleur communique et qui sera chargée de communiquer avec le magasin de données et de gérer la logique de tri. Pour les petites applications, il est cependant bien de s'asseoir dans le contrôleur.

0
Dismissile

C'est une question posée en pensant à asp.net, mais comme quelqu'un a mentionné Rails, j'ai pensé qu'il serait intéressant de considérer le problème dans ce contexte. Dans Rails, il est naturel et assez courant d'effectuer le tri avec la récupération en tant qu'action de contrôleur, car le framework et l'API ActiveRecord/ActiveQuery le prévoient. D'un autre côté, il est possible de définir une sorte d'ordre de tri personnalisé pour les éléments statiques et de le placer dans le modèle à utiliser par le contrôleur, afin que le modèle puisse jouer un rôle dans la logique de tri même s'il n'effectue pas l'opération directement. Quoi qu'il en soit, il peut être sûr de dire que mettre la logique de tri dans la vue est généralement mal vu.

Je suis légèrement amusé que certaines réponses soient absolument contre de mettre le tri dans le contrôleur ou le modèle, et je les trouve trop pédantes à mon goût, mais je suppose que cela dépend de la nature du cadre utilisé et des conventions habituelles associées à il. Je suis également d'accord avec le commentaire de Bill K selon lequel la séparation en premier lieu est plus importante.

0
prusswan