VB/VB.Net [Architecture] Organisation du code.

Shornaal

Membre Actif
Inscrit
17 Février 2011
Messages
194
Reactions
0
#1
Bonsoir !

Je viens demander votre aide car mon plus gros problème se présente dans l'architecture de mon code. Je manque sérieusement d'organisation. Pour utiliser plus tard sereinement mon code sur divers projets, j'aimerais séparer le bot (Connexion, traitement des packets et envoi.), l'affichage et l'accès aux fichiers externes (D2o/D2i qu'il faudrait que je commence à traiter, license, fichier de configuration etc...). Seulement j'ai beaucoup de mal à organiser tout ça seul et mon projet part dans tout les sens. Je sais que ça va me causer du tords et qu'à ce rythme je vais devoir recommencer.

Donc, avez vous des conseils pour séparer logiquement ces différentes parties du code ? Comment avez vous organiser votre projet ? Avez-vous des liens vers de bons tutoriels sur ce sujet (Architecture MVC en VB.Net, oui mais comment ?).

Merci d'avance, Shornaal.
 
A

Anonymous

Invité
#2
Désolé du retard de la réponse ^^'
Tu peux créer des dossiers si ce n'est pas déjà fait.
Ensuite tu créer des Module (ou Class je ne sais plus) et tu ajoutes des Sub.
Exemple: ExternFiles.vb -LoadLicense
-LoadConfig
-CreateDirectories, etc...
En espérant t'avoir aider :)
 
Inscrit
19 Octobre 2010
Messages
214
Reactions
0
#3
@Sabok : Je sens que ta réponse, elle va lui couper la chique !

@Shornaal : Il est difficile de faire une réponse utile qui soit concise : c'est un vaste sujet. Un peu le corrolaire de ton topic précédent : viewtopic.php?f=51&t=667&p=7527#p7527

Au niveau du découpage grossier, pour bien faire, il faudrait :
- [1] mettre dans un (ou plusieurs) assemblies à part (dll) tout ce qui touche à la mécanique générique : ce qui n'est pas spécifique à Dofus. Cette couche (layer) ne doit (en principe) pas dépendre de l'implémentation des autres couches.
- [2] mettre dans un (ou plusieurs) assemblies tout ce qui est dépendant de Dofus, mais indépendant du bot proprement dit : décodage des paquet, reader D2O, maps et pathfinding, envoi/reception de messages...
Avantages : Les mises à jour de Dofus n'affectent que cette couche, le plus souvent.
Il est facile de partager cette couche avec différents projets
- [3] le bot proprement dit, utilisant les services des couches [1] et [2].
[3.1] Isoler tout ce qui concerne l'IHM
[3.2] Isoler tout ce qui touche à la gestion des données
[3.3] Isoler le traitement des messages

Cependant, il faut être conscient qu'un tel découpage complexifie nettement la mise en place et le démarrage du projet. Par contre, ça en simplifie grandement l'évolution et c'est plus agréable.
Dans certains cas, on peut limiter ce cloisonnement (pour simplifier le développement) tout en gardant une bonne visibilité, avec les classes partielles. Chaque partial regroupant ce qui concerne un aspect.
Par exemple, j'ai une classe "PlayerCharacter", qui intègre une partie base de données dans PlayerCharacter.Database.cs, la gestion des messages dans PlayerCharacter.Messages.cs, ce qui impacte l'IHM dans PlayerCharacter.visual.cs ect...
De la même façon, on aura pour la gestion des comptes, Account.Database.cs, Account.Messages.cs....

Concernant le traitement des messages, il est intéressant de passer par des évènements pour que toutes les classes concernées voient passer les messages et traitent ceux qui la concerne (pour éviter le méga-switch-de-la-mort-qui-tue) .
 

Shornaal

Membre Actif
Inscrit
17 Février 2011
Messages
194
Reactions
0
#4
Décidément FastFrench, tes conseils sont précieux ! J'étais parti sur la première solution que tu as émis, en un peu plus condensé. Seulement, comme tu l'as dis. Le lancement du projet est fastidieux et un peu démotivant. Surtout quand on travail seul. Je pense que mes connaissances de la technologie DotNet et de l’orientation POO de celui-ci ne m'est pas encore suffisante pour le faire correctement. Je pense que je vais partir vers l'optique des classes partielles. Un peu de recherche, quelques essayes sur des applications moins conséquentes. (Ça tombe bien, j'ai un logiciel de gestion pour l'association de commerçants de ma ville à développer ! :D.). Et je tenterais ma chance dans un nouveau projet ! Il faudrait aussi que je me renseigne un peu plus sur les évènements en VB.Net pour en utiliser tout le potentiel. C'est dommage que le forum ne comporte pas encore de tutoriels sur cette facette du développement, ça en aiderait plus d'un je pense... En tout cas, merci pour ton aide. :)

PS Sabok : Je pense que l'intention était louable mais j'ai dépassé les concepts très basique depuis un petit moment. Merci tout de même. ^^.
 
A

Anonymous

Invité
#5
Quoi que tout ça est un sujet très complexe, je crois que pour un bot de base on peut déjà voir quelques composantes distinctes seulemenet en se basant sur les sources de dofus:

-Un module de gestion des communications
-Un pour les messages (ou packets)
-Un autre pour les types (ou data)
-Un pour la lecture des fichiers

Il y a un seul point ou je ne suis pas entièrement d'accord avec FF, c'est que les modules ne doivent pas dépendre l'un de l'autre. Je crois qu'il faut impérativement que les modules travaillent ensemble pour arriver à un tout intéressant. Par contre, il faut essayer de simplifier le plus possible l'intéraction entre ces modules pour permettre une maintenance plus aisée. Par exemple, un module ne doit pas faire d'actions complexes qui dépend de plusieurs variables d'un autre module, si on en arrive à çelà, il est probablement mieux d'essayer d'ajouter cette fonctionnalité au premier module à la place. L'utilisation d'interfaces peut très bien convenir pour l'interaction entre modules.

Ensuite, avant de se lancer dans le code, il faut bien voir les responsabilités de chanque modules ainsi que leur interactions. Un petit schéma peut être très utile dans ce cas (Sur papier, avec visio ou même mspaint). Voici un exemple simpliste de l'interaction que pourrait avoir les modules mentionnés ci-dessus:

Le module de messages prends les données récupérés par celui de communications, il instancie ses messages en utilisant les types dans le module de données. Pour le dernier module (lecture d20), il peut probablement être complètement à part (ou bien utilisés certaines classes du module data, tel que pour représenter une map, un item, un monstre, etc.).

Au final, l'interaction ressemble à ca:

network <- message -> data <- d20

Bon ce n'est qu'une façon de faire parmi tant d'autres, mais je crois que ca peut être un bon début pour un programmeur dofus débutant.
 

bouh2

Membre Actif
Inscrit
12 Septembre 2008
Messages
184
Reactions
21
#6
Quand FF dit que les modules doivent être indépendant ce n'est pas pour tout les modules. Par exemple ton module qui fourni les classes du protocole de dofus et les outils pour lire les d2o ne doit surtout pas dépendre du module du bot (comportement du bot), l'inverse par contre est vrai, le bot dépend du module protocole.
 

Shornaal

Membre Actif
Inscrit
17 Février 2011
Messages
194
Reactions
0
#7
D'abord, merci pour vos réponses qui sont toutes particulièrement utiles et qui m'ont permit de faire un jolie schéma idéal sur le tableau près de mon ordinateur !

FastFrench a dit:
Concernant le traitement des messages, il est intéressant de passer par des évènements pour que toutes les classes concernées voient passer les messages et traitent ceux qui la concerne (pour éviter le méga-switch-de-la-mort-qui-tue) .
Cette phrase est le seul élément de réponse qui m'échappe un peu. Comment chaque classe une par une peut passer par l'événement pour éviter le Switch ? Je pensais que l'événement déclenchait simplement le parsage (Ça ce dit ça?) des packets avant de demander à une fonction l'action de réponse à faire (Le corps du bot en somme.), non ?
 

bouh2

Membre Actif
Inscrit
12 Septembre 2008
Messages
184
Reactions
21
#8
Ça dépend aussi si tu cherches les performances le switch c'est le plus rapide comparé à a l utilisation de delegates ou autre. Propreté ou rapidité, il faut choisir :p
 
Inscrit
19 Octobre 2010
Messages
214
Reactions
0
#9
Shornaal a dit:
FastFrench a dit:
Concernant le traitement des messages, il est intéressant de passer par des évènements pour que toutes les classes concernées voient passer les messages et traitent ceux qui la concerne (pour éviter le méga-switch-de-la-mort-qui-tue) .
Cette phrase est le seul élément de réponse qui m'échappe un peu. Comment chaque classe une par une peut passer par l'événement pour éviter le Switch ? Je pensais que l'événement déclenchait simplement le parsage (Ça ce dit ça?) des packets avant de demander à une fonction l'action de réponse à faire (Le corps du bot en somme.), non ?
Le principe des évènements, c'est que tous les objets intéressés par tel ou tel évènement peuvent s'y abonner. Cela n'a rien d'exclusif (plusieurs objets peuvent être abonnés au même évènement).
Comme l'indique Bouh2, cela peut avoir des effets sur les perfs si on en abuse, mais dans le cas d'un bot gérant jusqu'à 8 comptes, et tant que l'on reste raisonnable au niveau du nombre d'objets abonnés (disons quelques dizaines d'objets abonnés maxi), tu ne constateras rien de sensible au niveau perfs. Ca devient plus critique si tu vises la gestion de milliers de connexions simultanées.

C'est surtout au niveau des objets éphémères qu'il est important de les désabonner pour qu'ils puissent être détruits (et éviter d'avoir des listes d'abonnés qui s'allongent au fur et à mesure).

Ainsi, si tu as une classe permettant de décoder les messages, elle devrait exposer au moins un évènement du genre "OnMessageReceived" (et probablement d'autres, pour être plus fin). Et le message proprement dit sera l'une des informations transmises pour le traitement de cet évènement, ainsi que d'autres infos utiles (timestamp, erreurs...).

Après, si tu veux intégrer un mécanisme de traces pour les messages échangés, il suffit d'abonner l'objet correspondant : tu n'a pas à modifier la classe décodant les messages. Idem si tu veux ajouter un feed-back au niveau de l'IHM...
 

Shornaal

Membre Actif
Inscrit
17 Février 2011
Messages
194
Reactions
0
#10
Donc en gros, au lieu de mettre en écoute l'événement une fois et déclenchez le décodage puis la switch une fois à un endroit. On peut mettre l'écoute à divers endroits et effectuer plusieurs actions à la suite ? J'ai un peu du mal à me le représenter. Comment sait-on dans quel ordre sont alors traités les instructions ? Oh et qu'est ce que tu entends par Feed-Back ? Désolé de te poser autant de questions, c'est la première fois que je m'intéresse plus en profondeur à ce genre de questions et je manque cruellement de connaissances pour l'instant.
 
Inscrit
19 Octobre 2010
Messages
214
Reactions
0
#11
C'est l'idée, oui. C'est plus propre dans une logique POO, en ce sens que c'est chaque objet qui détermine les ressources auxquelles il doit accéder, et les ressources en question n'ont pas à le savoir.

Pour ce qui est de l'ordre, je dirais que si tu dois le savoir alors c'est pas bon :ugeek:
En principe, chaque traitement effectué sur le message doit être indépendant des autres. Le plus souvent, le message sera utilisé "réellement" à un seul endroit (par réellement, je veux dire qu'il va affecter le fonctionnement du bot, et notamment provoquer une réaction de la part du bot comme l'envoi d'un message vers le serveur). Après, si les autres usages consistent à mettre à jour l'IHM (changer la couleur d'un indicateur, mettre à jour la carte...), peu importe dans quel ordre celui-ci sera executé.

Si vraiment l'ordre est important, alors il peut être utile de proposer deux ou trois évènements au lieu d'un seul (pour les controls, on a ainsi souvent "XXXChanging" suivi de "XXXChanged").
OnPreReceivingMessage
OnReceivingMessage
OnMessageReceived

Pour "feed-back", je suppose qu'en français on doit dire "retour". C'est ce que fait le programme (bot) en réaction au stimulus (réception du message), notamment de façon visuelle.
 
Haut Bas