IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

ref circulaire : comment separer des classes en projets ?


Sujet :

Windows Forms

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut ref circulaire : comment separer des classes en projets ?
    Bonjour à tous,

    Voilà, je me pose une question existencielle, et je ne sais pas trop par quelle méthode m'y prendre...
    Je souhaiterai séparer ma solution (mon soft) en plusieurs projets qui seraient en fait mes différentes classes.
    Mon soucis est que dans chaque classe, j'ai une réference à l'objet parent et le parent a une(ou des) reference vers ses enfants.
    Si je fais ce qu'il faut pour que chaque classe soit connue des autres, je me retrouve avec des references circulaires...

    un exemple tout simple:
    imaginons une classe a et une classe b.
    a a pour enfant une ou des classes b
    La ou les classe b doivent connaitre leur parent de type classe a.

    Si on transcrit ça au niveau projet/solution/references ca donne :
    un solution "mon programme"
    un projet "classe a" avec une reference vers le projet "classe b"
    un projet "classe b" avec une reference vers le projet "classe a"
    Sauf que ce schema là n'est pas possible à cause du fait que cela produit une reference circulaire.

    Je voulais donc savoir comment est-ce que je pourrais arriver à ce que je recherche à savoir des classes séparées en projets (pour la maintenance et les updates c'est quand meme plus léger) tout en sachant que je dois typer le parent et les enfants à la fois ?
    Merci d'avance

    @ bientot

  2. #2
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    utilise des interfaces

    tu aura donc plusieurs projets :

    - projet1
    interface_a
    interface_b

    - projet2
    classe_a -> réference à projet1
    classe_a a des enfants de type interface_b

    - projet3
    classe_b -> référence à projet1
    classe_b a un parent de type interface_a

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Salut,

    Merci pour le tuyau ! (et désolé du retard de reponse, j'ai pas pu avant...)
    J'ai testé sur un projet tout simple et ça fonctionne nickel chrome.

    Par contre je me pose une question existancielle :
    Imaginons que tu aies une classe qui hérite d'une autre (classe B herite de A)
    Classe A possède une méthode ToString
    Tu souhaites la surcharger dans classe B
    Que mets tu dans ton interface sachant que :

    - Ton interface sert à pouvoir appeler toutes les méthode de ton objet qui se trouve dans un projet a part (Cf ton explication au dessus)
    - T'es obligé de surcharger la méthode de A dans ta classe B
    - Overrides n'est pas accepté dans une interface

    Merci d'avance
    @ +

  4. #4
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    c'est au niveau de la classe que c'est gérée
    si ton interface demande une sub rien ne t'empeche qu'elle soit dans une classe héritée et overridée je pense
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    je pense que tu devrais chercher des tutos sur les classes en .NET, l'héritage, polymorphisme ... un peut de tout quoi
    En effet si tu as une classe A ayant l'interface I_A et que tu décides d'hériter la classe B de A, tout en overridant une méthode de A, l'appel à cette méthode à travers l'interface va éffectivement appeller la méthode de B.
    D'ailleurs, si un code interne à A appelle cette methode tout en éttant de type B ( B qui décend de A ) , il va aussi se retrouver à appeller la methode de B.

    Franchement celà ne me semble pas très clair comme explication ... d'où l'intéret des tutos

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Re !

    smyley : Merci du conseil pour les tutos, mais je ne crois pas que ce soit nécessaire (je me sers déjà de ces principes (heritage, polymorphisme, interfaces...)). La question est trop particulière pour trouver une réponse dans des tutos généraux et je me demande si beaucoup de monde utilise la méthode que tu as donné afin de séparer des classes intimmement liées en projets. Bref, sperot51 a raison sur le principe : il suffit juste de déclarer une sub en overload et de réaliser l'override dans la classe implementant l'interface.

    Voilà ! Je continue de faire quelques recherches pour voir si je peux vraiment séparer ma solution en projets comme je le pense... c'est pas très évident m'enfin bon.

    @+

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    si si
    sur des projets évolutifs et/ou conséquent les interfaces sont plus que pratique

    ca permet aussi de par exemple faire une interface oiseau avec sub vole
    et ensuite d'avoir un createur de classe
    dim mon oiseau as Ioiseau = createur_oiseau("pie")
    qui lui va faire return new pie (ou merle etc...)

    ca sert aussi à caster des objets sur des fonctionnalités
    ctype(objet,Isauvegardable).sauvegarde
    comme ca des objets vraiment différents peuvent avoir des fonctionnalités similaires codées differemment
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Les deux principes que tu donnes, je les comprend sans problème, c'est d'ailleurs pour ca que je les utilise, c'est juste le pourquoi je les utilise qui est un peu particulier : eviter des references circulaires entre projets... Pour t'expliquer :
    Mon projet est assez blindé de réferences, il faut que j'y mette un peu d'ordre mais grosso modo je t'explique un peu le principe (détourné du réel principe, c'est un exemple qui reprend la meme structure)

    Imagines que tu fasses un soft pour afficher une carte de France (ou qui fasse un traitement sur toutes les entités géographiques de France).

    J'ai en gros :

    - Une classe engine (qui chapotte le tout) avec à l'interieur :
    * Une classe outils (qui s'occupe de l'échelle de la carte, d'aides à la saisie...)
    * Une classe panneau (qui va etre le conteneur graphique)
    * une collection de regions (j'ai bien précisé régions, ce qui sous entendu une collection fortement typée)
    * des méthodes classiques (reset, load, save...)

    - Une classe panneau qui herite d'un truc genre usercontrol ou autre (enfin un receptacle graphique quoi)

    - Une classe région qui possède :
    * Une reférence à ma classe engine (pour pouvoir remonter directement au moteur)
    * une collection fortement typée de départements

    - Une classe département qui possède :
    * Une référence à sa région
    * une collection fortement typée de villes...

    Et ainsi de suite.

    Mon but ici est de créer autant de projet que de classe que je viens d'ennoncer, ceci afin de permettre une maintenance plus légère et plus simple.
    Tu constateras que les classes se referent de façon circulaire : region a une reference vers departement (pour pouvoir utiliser un List (Of departement)) et departement a une reference vers region pour connaitre à quelle région il appartient.
    Là ou ca commence à etre compliqué c'est que l'exemple est un peu trop simplifié vu que je n'ai que des references vers le dessus ou le dessous.
    Je pense que mon projet doit s'en tenir à peu pres à ce genre de choses mais il se peut qu'il y ait eu quelques dérapages dûs à des ajouts faits en speed ou autres erreurs, il faut donc que je controle mes réferences pour etre sur de ne pas en avoir fait trop dans tous les sens.
    Mais en tout cas merci pour le coup de main !

    par contre, pour le moment il faut que je me penche sur un autre petit détail concernant les interfaces : l'heritage d'un objet n'ayant pas d'interface lui meme...
    Imaginons une classe A ayant une interface I_A
    une classe EXT d'un projet exterieur n'ayant pas d'interface
    A herite de EXT
    Comment faire pour pouvoir appeler les methodes de EXT sachant que je n'ai pas d'interface... Je pense qu'une réference vers EXT s'impose dans un projet, je vais tester ca et je confirmerai (donc ne vous cassez pas la tete à chercher, c'est en cours )

    edit : je confirme, une simple réference vers EXT dans le projet cherchant à utiliser des propriétés ou méthodes de EXT au travers de A suffit

    @+

  9. #9
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    les interfaces pourraient quand meme résoudre ton probleme, enfin à grand coup de remplacement s'il est deja fini

    mais tu fais un projet qui contient que les interfaces, qui est chargé en 1er
    et dans tous les autre projets tu ne pointe vers aucune classe, que les interfaces

    du coup la classe A qui dedans fait dim var as new B tu fais dim var as I_B = new B
    et donc var te donnera accès a tout ce qui est dans l'interface, donc ne mettre que les choses publiques dans l'interface

    et donc ca marche vu que le projet contenant les I est autonome et que tout le monde le référence lui et non les choses entre elles
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Oui oui, elles résolvent totalement mon besoin !
    Si tu veux, je preferais juste voir un peu plus tous les points de détails qui auraient pu gêner cette transition.

    Par contre corriges ça :
    tu fais dim var as I_B = new B
    il me semble que c'est plutot = new I_B dans notre cas, sinon il faudrait avoir une réference sur l'interface + la classe

    et dans tous les autre projets tu ne pointe vers aucune classe
    Sauf si tu utilises une librairie tierce partie sans interface, il faudra pointer vers cette lib

    Encore merci !
    @++

  11. #11
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    Citation Envoyé par zax-tfh
    il me semble que c'est plutot = new I_B dans notre cas, sinon il faudrait avoir une réference sur l'interface + la classe
    et non justement !
    impossible de faire new sur une interface
    la référence est faite par le AS
    donc là ton AS référera bien une interface, peut importe le new qui est fait derriere

    Citation Envoyé par zax-tfh
    Sauf si tu utilises une librairie tierce partie sans interface, il faudra pointer vers cette lib
    euh oui surement, enfin si tu parles d'une librairie dont tu n'as pas le code source
    et encore, si c'est fait en .NET tu peux le retrouver le code source et rajoute une implementation d'interface
    enfin si c'est une librairie tierce, elle ne référence rien de chez toi donc pas de référence circulaire

    NB : visual studio permet de définir l'ordre de chargement des projets
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  12. #12
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par sperot51
    si c'est fait en .NET tu peux le retrouver le code source et rajoute une implementation d'interface
    ou alors utiliser la reflexion

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Bon je crois que je viens de réaliser un truc là, concernant mon cas d'utilisation :
    En gros : le créateur doit avoir une reference vers l'objet à créer donc dans mon cas, pour ne pas avoir de reference circulaire, je ne dois pas donner la possibilité à mes deux classes de se créer mutuellement.
    Concretement :
    Classe A peut créer classe B ou l'inverse mais pas les deux en même temps, sinon ref circulaire.
    Ai-je bien saisi ?

    merci
    ++

  14. #14
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 172
    Points : 25 112
    Points
    25 112
    Par défaut
    moi pas trop en tout cas

    ce qui risque de pas aller c'est

    classe A
    dim machin as B

    classe B
    dim machin as A

    je viens de tester ca et ca plante en effet



    apres ce qui peut planter aussi c'est :
    projet 1
    classe A
    classe B
    dim var as new C

    projet 2
    class C
    class D
    dim var as new A

    dans ce cas là il faut que les classes soient toutes dans le meme projet
    vu qu'il ouvre les projets un à un
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  15. #15
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    est-ce vraiment nécéssaire de faire 1 classe par projet quand tu n'as pas la possibilité de créer une interface commune aux deux classes ?

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    sperot51 : c'est justement ce que je disais : l'exemple que tu cites est le cas ou A peut créer B ET B peut créer A.
    Les interfaces et tout le bataclan qu'on a expliqué au dessus ne pourra fonctionner que si une des deux classes créé l'autre et uniquement ceci, mais jamais les deux qui peuvent se créer l'une et l'autre.

    smyley : Mon but n'est pas vraiment de créer 1 projet pour 1 classe mais plutot de découper ma solution en plusieurs projets afin d'avoir plusieurs dll et pouvoir maintenir tout ca plus simplement et plus proprement.

    dans mon exemple avec la France ci dessus, on pourrait donner un exemple de projet :

    projet Région contenant :
    - Classe région
    - Classe Conseil Régional
    - Classe ...

    Tout cela pour que la région soit dans une seule et meme dll.
    Le jour ou le conseil régional change un process, on le change dans la classe puis on recompile uniquement le projet région.
    C'est assez interressant.
    De plus, mon appli étant commerciale, on fonctionne uniquement par le web (pour les Maj) donc j'aimerai éviter de faire télécharger toute l'appli si je ne recompile qu'une partie de la solution
    Vous voyez le principe ?

  17. #17
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    mais justement avec une architecture comme

    projet Région contenant :
    - Classe région
    - Classe Conseil Régional
    - Classe ...

    il n'y a pas de référence circulaire, la dll region utilise la dll conseil regionnal qui utilise ... mais pas l'inverse. Ce que j'ai compris des dlls c'est que c'est une solution éfficace que lorsqu'il y a une hierarchie bien définie cf.
    A
    |
    B
    | \
    C D

    D ne peut pas référencer quelque chose appartenant à C car D et C sont sur le même "niveau". C'est pour celà que depuis le début je t'avais proposé de passer par les interfaces car si C est modifié, tu ne recompiles que C mais si B est modifié, tu devrais recompiler B,C et D. Apparament ce que tu veux c'est que D utilise C tout en sachant que C utilise D et dans ce cas je ne vois pas d'autres solution que de fusionner C et D, car sinon même avec un crayon et une feuille tu va avoir une référence circulaire

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Ton exemple est nickel pour que j'explique exactement la situation :

    Mon cas n'est pas celui que tu décris (sauf si je suis parti en live à cause de coups de bourre, ce que je n'espere pas, c'est ce que je disais plus haut, il faut que je le vérifie)

    Mon cas est le suivant :

    B connait C et C DOIT connaitre B
    idem pour D
    Sachant que j'entend par "connaitre" le fait de tout connaitre : propriétés, methodes... Donc dans ce cas là => Interfaces ! comme tu me l'as préconisé au départ.

    Le dernier truc qui me chagrinais c'était de comprendre le fait que l'on doive avoir une réference vers l'objet que l'on créé.
    Pour exemple :

    B va créer une instance de C donc dans le projet de B je dois avoir une reference vers le projet de la classe C

    Là ou ca ne passerai pas c'est si maintenant je disais : c'est bien cool mais C doit pouvoir créer un B' (B prime) => là c'est direct reference circulaire (B a une reference vers C pour créer C et vice versa).

    Donc je pense qu'on a fait le tour du problème. Ce qui me fait peut etre un peu peur c'est ma conception... Le projet est assez gros et chiadé donc je m'engage dans une sacrée transformation ou plutot un sacré checkup/vérification.
    J'espere que tout se passera bien...

    Pour le moment j'ai transformé mes classes du plus bas niveau et tout passe bien, là je vais attaquer un niveau au dessus (donc les classes se servant de celles que je viens de faire), on va voir ce que ca va donner ^^

    Encore merci à tous pour cet eclaircissement, et je pense que ce topic est a garder sous le coude

    @bientot

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 19/02/2006, 17h59
  2. Réponses: 2
    Dernier message: 01/02/2006, 15h02
  3. comment utilisé des classes toute prêtes
    Par Burinho dans le forum Langage
    Réponses: 3
    Dernier message: 23/01/2006, 22h18
  4. Réponses: 5
    Dernier message: 15/02/2005, 10h32
  5. [debutant] Comment ajouter des .class ?
    Par Slein dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 30/04/2004, 14h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo