web-dev-qa-db-fra.com

Comment séparer l'interface utilisateur de la logique métier tout en conservant son efficacité?

Disons que je veux montrer un formulaire qui représente 10 objets différents sur une zone de liste déroulante. Par exemple, je veux que l'utilisateur choisisse un hamburguer parmi 10 différents qui contiennent des tomates.

Puisque je veux séparer l'interface utilisateur et la logique, je devrais passer sous la forme d'une représentation sous forme de chaîne des hamburguers afin de les afficher sur la zone de liste déroulante. Sinon, l'interface utilisateur devrait creuser dans les champs des objets. Ensuite, l'utilisateur choisirait un hamburguer dans la zone de liste déroulante et le soumettrait au contrôleur. Maintenant, le contrôleur devrait retrouver ledit hamburguer sur la base de la représentation de chaîne utilisée par le formulaire (peut-être un ID?).

N'est-ce pas incroyablement inefficace? Vous aviez déjà les objets dont vous vouliez en choisir un. Si vous avez soumis au formulaire l'ensemble des objets, puis renvoyé un objet spécifique, vous n'auriez pas à le retrouver ultérieurement car le formulaire a déjà renvoyé une référence à cet objet.

De plus, si je me trompe et que vous devez réellement envoyer l'objet entier au formulaire, comment puis-je isoler l'interface utilisateur de la logique?

20
Uri

Tout d'abord, l'exemple que vous avez fourni n'est pas incroyablement inefficace; ce n'est que légèrement inefficace; son inefficacité est inférieure au niveau perceptible. Mais, en tout cas, passons à la question.

D'après ce que je comprends, lorsque nous parlons de séparation de l'interface utilisateur et de la logique , nous voulons dire évitement de couplage étroit .

couplage étroit fait référence à la situation dans laquelle l'interface utilisateur connaît (et invoque) la logique, et la logique connaît (et invoque) l'interface utilisateur. Pour éviter un couplage étroit, il n'est pas nécessaire de supprimer complètement le couplage. (C'est ce que vous semblez viser en démolissant l'interface entre eux en une interface de chaîne au plus petit dénominateur commun.) Tout ce qu'il faut faire est d'employer couplage lâche .

Couplage lâche signifie que A connaît B, mais B ne connaît pas A. En d'autres termes, les deux parties impliquées jouent un client distinct et rôles serveur , où le client connaît le serveur, mais le serveur ne connaît pas le client.

Dans le cas de l'interface utilisateur et de la logique, la meilleure façon d'organiser cela à mon avis est de voir la logique comme un serveur et l'interface utilisateur comme un client. Ainsi, l'interface utilisateur est conçue pour la logique, a connaissance de la logique et appelle la logique, tandis que la logique ne sait rien de l'interface utilisateur et répond simplement aux demandes qu'elle reçoit. (Et ces demandes proviennent de l'interface utilisateur, mais la logique ne le sait pas.)

Pour le dire en termes plus pratiques, vous ne trouverez nulle part dans les fichiers de code source de la logique des instructions d'inclusion/importation/utilisation faisant référence à des fichiers d'interface utilisateur, tandis que les fichiers de code source de l'interface utilisateur seront remplis d'inclusion/importation/utilisation les instructions qui font référence aux fichiers logiques.

Donc, pour revenir à votre cas, il n'y a absolument rien de mal à ce que le code de l'interface utilisateur qui remplit la zone de liste déroulante connaisse la classe des hamburgers. Il y aurait un problème si la classe de hamburger savait quelque chose sur les combos.

Soit dit en passant, cette conception permet une autre chose que vous devriez attendre d'un tel système: il devrait être possible de connecter autant d'interfaces différentes que vous le souhaitez à la logique, et le tout devrait toujours fonctionner.

36
Mike Nakis

Vous devez séparer chaque pièce du modèle, de la vue et du contrôleur, mais il n'y a aucune raison pour laquelle vous ne pouvez pas (par exemple) passer des objets de modèle entre le contrôleur et la vue.

Donc, dans votre cas, les objets Hamburger feraient partie du modèle. Vous utilisez ensuite votre contrôleur pour récupérer la liste requise de Hamburgers, et passez ces objets à la vue (la zone de liste déroulante) pour les afficher. Lorsque votre utilisateur a sélectionné quel hamburger, vous pouvez ensuite renvoyer l'objet Hamburger au contrôleur pour traitement.

Le fait est que vous pouvez toujours tester séparément la logique "fetch Hamburgers" et la logique "process Hamburger" séparément de l'affichage réel des hamburgers.

5
Dean Harding