2 votes

Une question très simple sur la façon dont l'interface graphique s'intègre aux classes logiques.

Supposons que j'ai un énorme formulaire de saisie, qui représente bien sûr des classes. J'ai besoin que cette saisie soit chargée dans les instances de la classe. Cette saisie contient évidemment des contrôles (de validation très compliqués), la couche logique contient évidemment déjà cette validation de saisie. la question est de savoir ce que je fais avec le gui.

Dois-je simplement, de manière très laide, réécrire toutes ces validations dans l'interface graphique ?

Ou dois-je écrire des méthodes statiques dans la couche logique, puis utiliser ces méthodes dans l'interface utilisateur et dans la couche logique, tout en créant une duplication de la validation elle-même (d'abord l'interface utilisateur se valide, puis la logique valide ce qui lui est envoyé) ?

Ou dois-je simplement supposer que l'interface graphique est correcte, entourer le code pertinent qui utilise la couche logique, avec un bloc d'essai, et ensuite, si une exception est levée, informer l'utilisateur que QUELQUE CHOSE ne va pas (sans lui donner l'occasion de savoir ce que c'est) ?

ou dois-je exposer l'exception, ce qui revient à lui exposer des paramètres, des classes et des noms d'espaces de noms, qu'il ne comprendra probablement pas.

Ou dois-je créer une classe d'exception spéciale pour chaque erreur, et informer ainsi l'utilisateur de la nature exacte du problème, tout en créant des centaines d'exceptions possibles ?

Ou devrais-je les séparer en exceptions générales, qui incluent toutes une énumération décrivant le contenu exact de l'erreur, puis attraper ces exceptions, et en vérifiant l'énumération informer l'utilisateur de ce qui est exactement le problème, mais rendre l'application plus lourde en attrapant inutilement des exceptions tout le temps.

ou devrais-je (quelqu'un me l'a proposé, ce n'est pas mon idée, ne me criez pas dessus :D) valider l'entrée dans la couche logique, et ne la vérifier que dans l'interface graphique (cela me semble être une solution absolument horrible :D)

et une question beaucoup plus importante - où dois-je apprendre de telles choses ? En général, mon instinct est assez bon, mais je ne veux pas inventer inutilement la roue (je suis presque sûr qu'il existe déjà des conventions pour des choses aussi élémentaires que celles que l'on rencontre tous les jours).

Merci beaucoup !

3voto

Nader Shirazie Points 8494

Il est certain que vous devez valider les entrées des utilisateurs. Si les entrées et la logique de validation sont aussi complexes que vous le dites, il est encore plus important de valider les entrées dans l'interface graphique, d'une manière qui rende évidentes pour l'utilisateur les valeurs attendues et, s'il y a des erreurs, ce qu'elles sont. Des points bonus si vous pouvez suggérer comment corriger ces erreurs !

Il n'est vraiment pas utile pour l'utilisateur de voir des exceptions et des détails d'exception - essayez donc d'éviter cela.

De plus, comme il s'agit d'une validation d'entrée dans l'interface graphique, et qu'une mauvaise entrée est attendue et ne sort pas vraiment de l'ordinaire, l'utilisation d'exceptions n'est pas nécessairement une bonne idée. Un simple IsValid() pour vérifier si quelque chose est valide ou non est préférable. Je suis toujours la règle qui dit que "les exceptions sont pour les circonstances exceptionnelles".

Si l'on admet que la validation dans l'interface graphique est une bonne chose, la question suivante est : comment ?

Vous dites que vous avez déjà mis en place un grand nombre de validations, mais il ne semble pas que votre logique de validation soit disponible séparément. Une pratique que j'ai toujours trouvée utile consiste à séparer le code de validation des autres logiques d'entreprise. Cela vous permet de réutiliser la logique de validation le cas échéant et, dans ce cas, de partager la même logique de validation entre vos objets métier et l'interface graphique. Il existe évidemment de nombreuses approches et cadres de conception pour y parvenir, mais le principe fondamental est la "séparation des préoccupations" - maintenir la logique de validation séparée et la rendre disponible pour utilisation. Vous semblez penser à la même chose lorsque vous dites "écrire quelques méthodes statiques dans la couche logique, puis utiliser ces méthodes dans l'interface graphique et dans la couche logique", et c'est une approche qui a fait ses preuves.

Par souci de clarté, je ne suggère pas de mettre la logique de validation dans l'interface graphique elle-même. Il s'agit plutôt de rendre la logique de validation disponible pour être utilisée par l'interface graphique. La seule partie de la validation qui devrait se trouver dans l'interface graphique est la partie qui prend les entrées de l'utilisateur (pour les soumettre à la validation) et la partie qui affiche les résultats de la validation (à l'utilisateur).

Edita:

Je ne voudrais pas passer pour un défenseur d'une philosophie de conception particulière, mais ces derniers temps, j'ai travaillé davantage selon les principes de la conception pilotée par les domaines (Domain Driven Design). J'ai trouvé que cela fonctionnait très bien et que cela répondait à beaucoup des questions que vous posez. Il y a quelques questions sur SO qui donnent plus de détails sur ce que c'est et où il y a des ressources :

https://stackoverflow.com/questions/1353742/domain-driven-design-ddd-readings
Qu'est-ce que la conception pilotée par les domaines ?

Vous pouvez également consulter cette page : http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/02/15/validation-in-a-ddd-world.aspx

Editer 2 :

Une lecture utile (et connexe) également : Business Objects, validation et exceptions

1voto

Josh Smeaton Points 18165

Je viens de terminer un projet très similaire dans le cadre de mon travail. J'avais 3 formulaires assez volumineux et un grand nombre de classes représentant les données requises. Chaque classe avait une méthode bool IsValid().

Lorsque l'utilisateur clique sur le bouton "Enregistrer", une méthode est appelée pour construire toutes les classes à partir des éléments d'entrée du formulaire. Chaque propriété a une validation très simpliste (type, valeurs par défaut si elles ne sont pas définies, etc.) Une fois que toutes les classes sont construites (dans une structure arborescente - une classe de haut niveau contenant un grand nombre d'autres classes), la méthode IsValid est appelée sur le parent qui, à son tour, appelle IsValid sur tous ses enfants.

Si IsValid renvoie False, la propriété Errors du parent est remplacée par les propriétés Errors de tous ses enfants qui ont échoué à l'appel IsValid. J'affiche ensuite les erreurs dans une vue conviviale.

Cependant, dans certains cas, j'ai dû valider certains critères avant de cliquer sur le bouton d'enregistrement, et j'ai fourni des méthodes pour les classes concernées.

Je ne pense vraiment pas que vous devriez mettre la validation dans la classe GUI. Chaque classe devrait être responsable de ses propres exigences en matière de validation. Cependant, je pense qu'il est possible d'utiliser l'interface graphique pour fournir des "indices" à l'utilisateur sur les zones du formulaire qui sont nécessaires, par exemple en utilisant des événements de changement pour activer ou désactiver des parties du formulaire.

Je pense que, généralement, c'est une bonne idée d'écrire toute votre logique et vos classes de telle sorte que vous n'ayez pas besoin d'une interface graphique. Et si vous vouliez créer une interface console au lieu d'une interface Windows Forms ? Vous devriez être en mesure d'échanger l'un contre l'autre sans changer les classes d'entreprise que vous avez déjà.

0voto

Paul Keister Points 7179

C'est une excellente question. L'idée de placer les validations dans la couche de données est une notion classique de l'OO, mais lorsque le caoutchouc rencontre la route, cela peut être gênant. J'aime l'idée de placer les règles de validation d'une entité dans leur propre classe afin qu'elles puissent être réutilisées.

J'utilise généralement une approche en couches pour la validation des données, la couche supérieure (la couche de présentation) contenant le code le plus sophistiqué et le plus utile. Dans la couche intermédiaire et la couche de données, la validation se concentre sur la validation des assertions et le lancement d'exceptions lorsque des données non valides sont rencontrées. L'idée est que vous attendez de la couche de présentation qu'elle valide complètement les données, mais que, dans le cas où des données non valides parviennent à passer, vous voulez protéger la logique de l'entreprise et fournir de bons diagnostics. Vous ne voulez certainement pas montrer une exception brute à un utilisateur, mais il est bon de préserver les informations relatives à l'exception afin de pouvoir y accéder. Par exemple, vous pouvez écrire une trace d'exception dans un fichier journal et/ou vous l'envoyer à vous-même dans un message électronique et/ou l'afficher à l'utilisateur dans le contexte approprié si vous pensez que l'utilisateur peut la gérer.

Lorsque l'on considère les particularités de la validation des données, l'idée classique de créer un objet qui "sait" comment se valider lui-même devient moins utile qu'il n'y paraît à première vue. Chaque couche de validation répond à des préoccupations quelque peu différentes. Même si les règles métier sous-jacentes déterminent les validations à tous les niveaux, la réponse aux données non valides est différente selon le contexte du code. La principale différence est que, dans la couche de présentation, vous voulez vraiment vous concentrer sur une communication claire avec l'utilisateur et sur la création d'une bonne expérience utilisateur face à des données non valides. Il est logique que ce code soit intégré dans les écrans et les contrôles individuels.

Il est fortement conseillé de distiller des règles de gestion simples et atomiques dans des fonctions ou des constantes simples au sein de classes dédiées à la validation. Vous pouvez également placer ces règles dans des fonctions statiques sur les classes de la couche de données, comme vous le suggérez. L'essentiel est de ne définir les règles de validation qu'une seule fois. Par exemple, si l'application limite une valeur entre 10 et 100, les constantes 10 et 100 ne devraient apparaître qu'une seule fois dans votre code. Mais ces constantes, ou une simple fonction qui effectue la validation de la plage, seront utilisées par plusieurs fonctions de validation dans différents niveaux.

Dans le même ordre d'idées, il est également possible de définir des assemblages de validation composés de classes ne comportant que des constantes de validation et des fonctions de validation simples. Ces assemblages de validation peuvent ensuite être chargés dans le SQLCLR et utilisés pour la validation de la couche de base de données. De cette manière, les mêmes définitions de validation peuvent couvrir l'ensemble du système jusqu'à la couche de la base de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X