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

19

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 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?

Uri
la source
En quoi serait-il inefficace? Dans tous les cas, vous devez montrer une représentation de chaîne à l'utilisateur et mapper sa réponse à l'objet d'origine.
Simon Bergot
Le problème est que pour travailler avec ledit objet, je dois le récupérer à nouveau après que l'utilisateur l'ait choisi.
Uri

Réponses:

34

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 entendons éviter le couplage étroit .

Le 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 recourir à l'abolition totale du 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'utiliser un couplage lâche .

Un 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 des rôles client et serveur distincts , 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.

Mike Nakis
la source
5

Vous devez séparer chaque élément 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 Hamburgerobjets 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 Hamburgerrenvoyer l' objet au contrôleur pour traitement.

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

Dean Harding
la source
Je comprends. Cependant, si je modifie la classe Hamburguer, ne devrai-je pas également modifier le code du formulaire qui traite des objets Hamburguer? Où est alors la séparation UI-Logic?
Uri
2
Le hamburger fait partie du modèle. Lorsque vous modifiez le modèle, vous finissez par modifier la vue et le contrôleur. Le modèle est la séparation entre l'interface utilisateur et la logique. Le toucher a un coût plus élevé, vous devez donc être prudent lors de sa conception.
Simon Bergot