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

VB.NET Discussion :

Affectations entre 2 classes


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 7
    Par défaut Affectations entre 2 classes
    Bonjour,

    J'aurais souhaité savoir si il y avait un danger à liées deux classes entres elles par double affectation.

    Voici un exemple pour illustrer ma question : J'ai deux classes, Propriétaire et Voiture, pour les quelles à chaque Propriétaire correspond une unique Voiture, et pour chaque Voiture un unique Propriétaire. Puis-je lier mes classes Propriétaire et Voiture de la manière suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    Class Propriétaire
        Public Nom as String
        Public Voiture as Voiture
     
        Public Sub New(m_Nom as String)
            Nom = m_Nom
            Voiture = New Voiture(Me)
            ListeVoiture.Add(Voiture)
        End Sub
     
    End Class
     
    Class Voiture
        Public Marque as String
        Public Couleur as Color
        Public Propriétaire as Propriétaire
     
        Public Sub New(m_Propriétaire as Propriétaire)
            Propriétaire = m_Propriétaire
        End Sub
     
    End Class
     
    Public Sub Main()
     
        Dim ListeVoitures as New List(of Voiture)
        Dim Propriétaire1 as New Propriétaire("Toto")
     
        'Récupération du nom du propriétaire de la première voiture de la liste
        Msgbox(ListeVoitures(0).Propriétaire.Nom)
     
    End Sub
    Le but de la manœuvre est de pouvoir accéder aux propriétés du Propriétaire depuis l'objet Voiture. Est-ce une bonne solution ou y-a-t-il une solution plus élégante ?

    Merci pour votre aide !

    Nicolas.

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Par défaut
    Bonjour,

    Votre code révèle quelques confusions en matière d'approche objet.

    une unique Voiture
    Alors pourquoi une liste de voiture pour la classe propriétaire ?

    Deuxièmement il est bon d'accéder aux propriétés d'une classe via les accesseurs Get et Set et d'utiliser à l'intérieur de la classe une variable interne.
    Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Public Class Classproprietaire
     
        Private mNom As String
        Public Property Nom() As String
            Get
                Return mNom
            End Get
            Set(ByVal value As String)
                mNom = value
            End Set
        End Property
     
    End Class
    Ensuite dans la procédure New de propriétaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Voiture = New Voiture(Me)
    Ne va pas marcher, car il faut instancier avec le nom donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Voiture = New Voiture(Me.nom)

  3. #3
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Salut,

    Citation Envoyé par Nicorombe Voir le message
    J'aurais souhaité savoir si il y avait un danger à liées deux classes entres elles par double affectation.
    Le danger de ca c'est qu'il s'agit d'une référence circulaire, un objet A référence un object B qui lui même référence l'objet A, etc...
    Résultat, si ton code ne découple pas les deux à un moment ou à un autre, aucun de ces deux objets ne sera détruit, le garbage collector verra qu'ils sont tout deux référencés.

  4. #4
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Le danger de ca c'est qu'il s'agit d'une référence circulaire, un objet A référence un object B qui lui même référence l'objet A, etc...
    Résultat, si ton code ne découple pas les deux à un moment ou à un autre, aucun de ces deux objets ne sera détruit, le garbage collector verra qu'ils sont tout deux référencés.
    A cela il convient d'ajouter les problèmes de sérialisation avec des objets en références circulaires.

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Par défaut
    Bonjour,

    A cela il convient d'ajouter les problèmes de sérialisation avec des objets en références circulaires.
    Parfaitement d'accord avec vous mais il m'avait semblé qu'il fallait commencer par le début avant d'attaquer des problématiques plus complexes.

  6. #6
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Moi il me semble qu'il est bien plus complexe de prendre en compte ce genre de chose a priori plutôt qu'a postériori. Revenir sur ce genre de chose peut demander un travail gigantesque en refactoring et même en recherche des occurrences de ces problèmes.

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Moi il me semble qu'il est bien plus complexe de prendre en compte ce genre de chose a priori plutôt qu'a postériori.

    Tu veux dire le contraire je suppose ?

    En effet :

    Revenir sur ce genre de chose peut demander un travail gigantesque en refactoring et même en recherche des occurrences de ces problèmes.

  8. #8
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Et donc, pour en revenir à la question de base (car elle m'intéresse également), comment fait-il pour savoir qui est le propriétaire de la voiture ?

  9. #9
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par griftou Voir le message
    Et donc, pour en revenir à la question de base (car elle m'intéresse également), comment fait-il pour savoir qui est le propriétaire de la voiture ?
    Et bien le plus "simple" a mon sens c'est que la classe Propriétaire embarque une valeur identifiant l'instance de manière unique (par exemple le nom du propriétaire si on peut considérer cette variable comme unique, ou carrément un identifiant supplémentaire du genre Guid).
    Ainsi, Voiture ne référence pas un objet Proprietaire, mais plutôt la valeur identifiant le propriétaire.
    Cette façon de faire permet de découpler les deux classes tout en gardant un moyen de retrouver le propriétaire.
    Par contre, elle impose recherche du propriétaire, plutôt qu'accès directe.

  10. #10
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par Geo2A Voir le message
    Ce que je voulais souligner c'est qu'avant d'aborder des notions complexes comme les références circulaires il faut déjà maîtriser la base en matière de POO.
    quand je lis m_Nom en paramètre d'une procédure New je me fais un peu de soucis. Mais bien évidement il vaut mieux avant de se lancer dans un programme complexe maîtriser l'ensemble des concepts. Ceci dit on a tous commencer par "Hello World".
    Plutot d'accord, cependant sa question c'était

    Citation Envoyé par Nicorombe Voir le message
    Bonjour,

    J'aurais souhaité savoir si il y avait un danger à liées deux classes entres elles par double affectation.
    Bah on a répondu à la question : le danger c'est que c'est une référence circulaire. Et on a donner deux exemples des effets pervers des références circulaires.

  11. #11
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Bah on a répondu à la question : le danger c'est que c'est une référence circulaire. Et on a donner deux exemples des effets pervers des références circulaires.
    On peut au demeurant (un peu) limiter l'impact via les WeakReference, mais on sort un peu du cadre de la programmation "débutant"

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 7
    Par défaut
    Merci à tous pour vos réponses.
    Il me semble effectivement que la solution la plus simple (et la moins dangereuse) soit d'ajouter une propriété Keyprop à chaque voiture qui identifie de manière unique le propriétaire.

    Par ailleurs, comme le signalait Geo2A :

    Deuxièmement il est bon d'accéder aux propriétés d'une classe via les accesseurs Get et Set et d'utiliser à l'intérieur de la classe une variable interne.
    Y-a-t-il une véritable différence à utiliser les structures Property pour accéder aux propriétés d'une classe plutôt que de les déclarer Public, ou s'agit-il plus d'une convention de programmation ?

    Merci.

  13. #13
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    On va dire que c'est une convention, mais qu'il vaut mieux la respecter.
    Le fait est qu'une property n'est pas une variable locale mais un jeu de deux méthodes (ou juste une seule, selon comment elle est déclarée).
    Cela signifie que tu peux ajouter du code dessus.
    Par exemple, sur un Set tu peux vérifier que la valeur est valide et lancer une exception si ca n'est pas le cas, chose que tu ne peux pas faire si on accède directement a la valeur.
    Tu peux également, sur le Get d'une propriété, t'assurer que l'instance existe et la créer si ce n'est pas le cas, ainsi, de l'extérieur, la propriété ne vaut jamais null.

    Et sinon, mais la on rentre dans un truc un peu plus complexe : la plupart des mécanisme de sérialisation, de binding, etc... fonctionnent via la reflection en obtenant la liste des propriétés de l'objet. Si tu met les membres en public pour ne pas avoir a déclarer de propriété, ils ne seront pas visibles à ces mécanismes, en conséquences tu ne pourra pas sérialiser tes objets (enfin si, y'a toujours moyen, mais tu va galérer alors que ca se fait tout seul si tu respecte la convention)

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Par défaut
    Bonjour,

    Y-a-t-il une véritable différence à utiliser les structures Property pour accéder aux propriétés d'une classe plutôt que de les déclarer Public
    Oui et elle n'est pas mince. C'est un concept essentiel de la programmation objet: l'encapsulation.

    En déclarant une variable Public au niveau d'une classe, n'importe quelle ligne de code à l'intérieur du programme pourra venir modifier cette variable.

    En utilisant les accesseur on déclare une variable membre à l'intérieur de la classe (mNom dans mon exemple) que l'on préfixe par habitude par m ou m_ (membre de). C'est cette variable qui sera utilisée à l'intérieur de la classe, qui sera ENCAPSULEE dans la classe, et seule les méthodes de la classe pourront l'affecter car la variable a pour portée la classe qui la contient. Elle sera invisible au autres objets du programme. La seule façon alors d'affecter la variable memebre depuis l'extérieur de la classe sera de faire un appel explicite à la propriété via l'accesseur set en écrivant:
    monobjet.Nom= machin et d'un point de vue interne à la classe cela déclenchera mNom=machin

    Est-ce clair ?

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 7
    Par défaut
    Merci, je comprends bien la différence maintenant.

    Et sinon, mais la on rentre dans un truc un peu plus complexe : la plupart des mécanisme de sérialisation, de binding, etc... fonctionnent via la reflection en obtenant la liste des propriétés de l'objet. Si tu met les membres en public pour ne pas avoir a déclarer de propriété, ils ne seront pas visibles à ces mécanismes, en conséquences tu ne pourra pas sérialiser tes objets (enfin si, y'a toujours moyen, mais tu va galérer alors que ca se fait tout seul si tu respecte la convention)
    Puisqu'on aborde ces mécanismes, j'en profite : je me sers effectivement de la reflection pour lister les propriétés de mes classes. Puisque toutes mes propriétés étaient déclarées en Public, j'utilisais jusque là quelque chose du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    myType = MonObjet.GetType()
    Try
        Dim myFields As FieldInfo() = myType.GetFields()
        For i As Integer = 0 To myFields.Length - 1
            Dim row As String() = {myFields(i).Name, myFields(i).GetValue(MonObjet)}
            DataGridView1.Rows.Add(row)
        Next i
    Catch ex As Exception
        Dim row As String() = {"Erreur", ""}
        DataGridView1.Rows.Add(row)
    End Try
    Si j'utilise maintenant des propriétés, la méthode GetValue() des PropertyInfo nécessite un argument supplémentaire index(). A quoi correspond-il ?

    Merci.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 22/11/2005, 11h12
  2. Comparaison entre les classes et les fonctions
    Par Ashgenesis dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 08/09/2005, 19h09
  3. Réponses: 5
    Dernier message: 17/08/2005, 12h40
  4. Pb accès entre 2 classes static
    Par d.w.d dans le forum C++
    Réponses: 5
    Dernier message: 23/02/2005, 19h05
  5. Affectation entre qrexpr et qrlabel
    Par souad26 dans le forum QuickReport
    Réponses: 2
    Dernier message: 30/01/2005, 11h25

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