J'ai développé plusieurs projets d'application Web au cours des 3 dernières années, à la fois personnels et professionnels, et je n'arrive pas à comprendre s'il est possible qu'au moins une logique métier ne se retrouve pas dans la couche d'affichage de l'application.
Dans la plupart des cas, il y aura des problèmes comme "Si l'utilisateur a sélectionné l'option x, l'application doit lui permettre de fournir des informations pour y, sinon il doit fournir des informations z". Ou effectuez une opération AJAX qui devrait appliquer certaines modifications au modèle mais PAS les valider jusqu'à ce que l'utilisateur l'ait explicitement demandé. Ce sont quelques-uns des problèmes les plus simples que j'ai rencontrés et je ne peux pas comprendre comment il est possible d'éviter une logique complexe dans la vue.
La plupart des livres que j'ai lus décrivant MVC présentent généralement des exemples très triviaux, comme les opérations CRUD qui mettent simplement à jour les données sur le serveur et les affichent, mais CRUD n'est pas le cas sur la plupart des applications riches.
Est-il possible d'obtenir une vue sans aucune logique métier?
la source
Réponses:
Je trouve que c'est une question trompeusement difficile à répondre. (Question qui fait réfléchir!)
Théoriquement, oui, selon ce que nous définissons comme logique métier. En pratique, une séparation stricte devient beaucoup plus difficile, et peut-être même indésirable.
La séparation des préoccupations est un excellent moyen de penser à la création de logiciels: elle vous donne des idées sur l'endroit où placer le code et elle donne aux responsables une bonne idée de l'endroit où chercher le code. Je dirai qu'il est fondamentalement impossible pour les humains de créer des logiciels qui fonctionnent sans séparation des préoccupations. Nous en avons besoin.
Mais, comme pour tout, il y a des compromis. Le meilleur emplacement conceptuel peut ne pas être le meilleur emplacement pour d'autres raisons. Peut-être qu'il y a trop de charge sur votre serveur Web, vous ajoutez donc du javascript à vos pages Web pour détecter les erreurs de saisie faciles avant qu'elles n'atteignent votre serveur; vous avez maintenant une certaine logique métier à votre avis.
La vue elle-même, à elle seule, n'a aucune valeur sans la logique métier. Et pour être efficace dans l'utilisation et l'affichage, implicitement ou explicitement, la vue aura une certaine connaissance des processus métier en cours. Nous pouvons limiter cette quantité de connaissances, et nous pouvons en boucler certaines parties, mais des considérations pratiques nous obligent souvent à «rompre» la séparation des préoccupations.
la source
The best conceptual location may not be the best location for other reasons
: Bravo !!Je fais généralement ceci: si l'utilisateur a sélectionné l'option x, la vue appelle
Ensuite, le contrôleur active y sur la vue:
La vue informe le contrôleur de ce qui se passe sans rien décider.
la source
Je me demande si les exemples que vous décrivez sont vraiment de la logique métier. Les exemples que vous décrivez sont des opérations qui peuvent être effectuées sur le système. C'est la façon dont vous avez choisi de présenter les choix à l'utilisateur qui donne peut-être l'impression que vous faites de la logique métier dans la vue.
Du point de vue "View", il fournit uniquement InfoY ou InfoZ au système. Ce n'est pas parce que votre implémentation d'interface utilisateur effectue des mises à jour dynamiques basées sur un choix d'opérateur (c'est-à-dire l'activation d'InfoY ou d'InfoZ) que la fonctionnalité est logique. C'est vraiment une logique d'implémentation de vue. Vous auriez très bien pu simplement donner à l'opérateur le choix d'entrer InfoY ou InfoZ sans l'activation complète. Dans ce contexte, considéreriez-vous toujours cela comme une logique métier? Sinon, la même chose s'applique pour l'activation / désactivation dynamique des champs d'informations.
Il en va de même pour l'exemple de validation. Il s'agit de 2 opérations distinctes dont le système a besoin pour fonctionner correctement. Votre vue doit être en mesure de lancer les actions appropriées pour exécuter la fonctionnalité souhaitée. Le fait de savoir comment utiliser votre système signifie-t-il une fuite de la logique métier? Je peux voir comment quelqu'un pourrait dire oui, mais si vous croyez de cette façon, la réalité est qu'il n'y a rien de tel que la séparation de la logique métier de quoi que ce soit. Vous devez savoir ce que le système fait / travaille pour accomplir quelque chose de significatif. Sinon, ce serait un jeu d'enfant de créer une seule vue et contrôleur générique qui fonctionne avec toutes les applications MVC imaginables. Ce que nous savons est impossible.
En bout de ligne, je pense que votre définition de la logique métier n'est pas la même que celle des autres.
la source
Je travaille de cette façon (Struts2 + Hibernate):
My Struts Actions est uniquement responsable de l'affichage des informations sur le navigateur Web. Ne pas penser.
Utilisateur -> Action -> Service -> Référentiel -> Accès aux données
Ou:
Je veux voir -> Comment voir -> Que faire -> Comment obtenir -> Où trouver
Donc, dans la première couche (la vue), j'ai quelque chose comme:
Comme vous le voyez, mon "point de vue" ne pense pas. C'est demander un service (pour gérer des cours) un cours spécifique. Ce service peut faire beaucoup plus de choses, comme des rapports, des seraches, etc. Le résultat est toujours une liste ou un objet spécifique (comme l'exemple). Les services sont la vraie machine, appliquent des règles et accèdent au référentiel (pour gérer les données).
Donc, si je place mes services, référentiels et DAOS dans différentes bibliothèques, je peux les utiliser même dans un programme texte ou un système de bureau Windows sans rien changer.
Le service sait quoi faire, mais ne sait pas montrer. La vue sait montrer, mais ne sait pas quoi faire. La même chose avec Service / Repository: Le service envoie et demande les données, mais ne sait pas où se trouvent les données et comment les prendre. Le référentiel "compose" les données brutes des objets de cuisine afin que le Service puisse travailler avec.
Mais le référentiel ne sait rien de la base de données. Le type de base de données (MySQL, PostgreSQL, ...) concerne DAO.
Vous pouvez modifier le DAO si vous souhaitez modifier la base de données et cela ne doit pas affecter les couches supérieures. Vous pouvez modifier le référentiel si vous souhaitez mettre à jour votre gestion des données, mais cela ne doit pas affecter le DAO et les couches supérieures. Vous pouvez changer les Services si vous voulez changer votre logique, mais cela ne doit pas gâcher les couches au-dessus ou en dessous.
Et vous pouvez changer quoi que ce soit en vue, même la technologie (web, bureau, texte) mais cela ne doit pas impliquer de toucher quoi que ce soit ci-dessous.
La logique métier est le service. Mais comment interagir avec cela, c'est voir. Quel bouton afficher maintenant? L'utilisateur peut-il voir ce lien? Vous pensez que votre système est un programme basé sur une console: vous devez refuser si le mauvais utilisateur choisit
#> myprogram -CourseService -option=getCourse -idCourse=234
ou l'arrête d'appuyer sur les touches pour écrire cette commande?Parler dans des systèmes basés sur le Web (Struts + JavaEE) J'ai un package de contrôleur GUI séparé. En vue Action, je donne à l'utilisateur connecté et la classe me donne les boutons (ou tout élément d'interface que je veux).
Et
N'oubliez pas de garder cela hors des services. Ce sont des trucs VIEW. Gardez-le dans les actions Struts. Toutes les interactions d'interface doivent être entièrement séparées du vrai code d'entreprise, donc si vous portez votre système, il sera facile de couper ce dont vous n'aurez plus besoin.
la source
C'est logique pour le modèle, pas pour la vue. Il peut s'agir d'un "modèle de vue", créé spécifiquement pour prendre en charge l'interface utilisateur, mais il s'agit toujours d'une logique de modèle. La séquence de contrôle est la suivante:
inputY.enable(model.yAllowed()); inputZ.enable(model.zAllowed());
UI View Controller Model |.checkbox X checked.> | | | | | .. X selected ...>| | | | |-----> set X ------->| | | | | | |< .............state changed ............| | | | | | |-------------- Get state --------------->| | | | | | |<----------- new state ------------------| | <-- UI updates ------|
Il s'agit du modèle MVC classique. Il est possible de tester complètement la logique du modèle indépendamment de l'interface utilisateur. Le contrôleur et la vue sont très fins et faciles à tester.=== En réponse à Dunk ===
Le modèle dans un modèle d'interface utilisateur MVC n'est (généralement) pas un modèle d'objet métier. Ce n'est que le modèle de l'état de l'interface utilisateur. Dans une application de bureau, il peut contenir des références à plusieurs modèles commerciaux. Dans une application Web 2.0, il s'agit d'une classe Javascript qui détient l'état de l'interface utilisateur et communique via AJAX au serveur. Il est très important de pouvoir écrire des tests unitaires interactifs du modèle d'état de l'interface utilisateur, car c'est là que se trouvent la plupart des bogues de l'interface utilisateur. La vue et le contrôleur doivent être des connecteurs très fins.
la source
Une logique métier ressemble plus à cela
If X then return InfoType.Y
, puis l'interface utilisateur affichera des champs en fonction du résultat renvoyé par le domaine.Si l'interface utilisateur nécessite une logique métier, déléguez le choix au domaine. L'interface utilisateur agira simplement sur la décision.
la source
Il existe des entrées qui ont des valeurs requises conditionnelles. Dans la plupart des environnements GUI, il existe de nombreux choix sur la façon de gérer les entrées, en particulier le timing. L'option sélectionnée (dans ce cas x) doit être traitée, alors envoyez-la au contrôleur. Envoyez-le lorsque les utilisateurs quittent le champ de saisie. Attendez qu'ils cliquent sur un autre objet ou appuyez sur enregistrer. Peu importe pour la logique métier. D'une manière ou d'une autre, le contrôleur prendra une décision et devra dire à la vue "y est requis".
La façon dont la vue interprète ou implémente cela n'a pas vraiment d'importance du point de vue de la logique métier. Faites votre champ obligatoire. Ayez une fenêtre contextuelle ou lancez un canon et dites à l'utilisateur d'entrer y ou tout simplement d'être têtu et de ne pas laisser le pauvre utilisateur faire quoi que ce soit avant d'avoir compris cela.
Et pensez-y, tout cela s'est peut-être produit parce que le contrôleur a tenté d'enregistrer et n'a pas entré de valeur pour un champ obligatoire dans la base de données et répondait uniquement à une erreur de base de données. Peu importe la vue.
Quelque chose comme une valeur requise ou limitée pour une entrée peut être gérée à de nombreux endroits. Si vous ne le résolvez "que" dans la vue, de nombreux développeurs voient cela comme un problème lorsqu'il peut y avoir plusieurs interfaces utilisateur. C'est pourquoi la logique métier peut être créée et testée sans beaucoup d'interface utilisateur ni même de base de données. Vous n'avez même pas besoin d'avoir un site Web.
la source