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 :

[DTO] Que faire des références circulaires ?


Sujet :

VB.NET

  1. #1
    Expert confirmé
    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 : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut [DTO] Que faire des références circulaires ?
    Bonjour,

    Je me pose une question concernant les classes métiers et la manière de l'organiser.

    Pour illustrer mon problème, voici un exemple simple.

    Dans la DB, nous avons :

    • une table Fournisseur avec pour colonnes F_Id (INT PK) et F_Nom (VARCHAR(50)).
    • une table Marque avec pour colonnes M_Id (INT PK) et M_Nom (VARCHAR(50)).
    • une table de jointure entre Fournisseur et Marque avec les colonnes F_ID et M_ID référençant les colonnes du même nom dans les tables précédentes et composant la clef primaire.

    Dans l'application, je suis dont tenté de créer une classe Fournisseur avec comme propriétés :

    • Id (Integer)
    • Nom (String)
    • Marques (List(Of Marque)) [qui contient les marques que ce fournisseur fournit]

    Je suis également tenté de créer une classe Marque avec comme propriétés :

    • Id (Integer)
    • Nom (String)
    • Fournisseurs (List(Of Fournisseur)) [qui contient les fournisseurs qui fournissent cette marque]

    Mon problème est le suivant :
    Au moment de l'instanciation d'un objet de type Fournisseur, je vais donc aller récupérer sa liste de marques. Au moment d'instancier un objet de type Marque (pour le mettre dans la liste), je vais aller récupérer sa liste de fournisseurs.


    Et le cercle vicieux est enclenché.


    Quelle est la bonne pratique pour ce genre de situation ?

    P.S. : J'ai trouvé une solution pour une référence circulaire à base "d'objets uniques". Mais vu qu'ici il s'agit de listes, je ne vois pas comment appliquer à cette situation.
    Kropernic

  2. #2
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Une solution consiste à :

    • Créer une List<Tuple<int,int>> refletant la table de jointure entre Fournisseur et Marque,
    • Ajouter aux classes Marque et Fournisseur une variable se référant à la liste de Tuple (liste passée dans le constructeur),
    • Créer dans la classe Marque une fonction List<Int> GetFournisserIds() exploitant la liste de tuples pour retourner les Id des Fournisseurs correspondant à l'Id de l'objet Marque,
    • Créer dans la classe Fournisseur une fonction List<Int> GetMarqueIds(),
    • Définir les classes Fournisseurs : List<Fournisseur> et Marques : List<Marque> qui seront de toutes façons utiles,
    • Créer dans la classe Fournisseurs la fonction Fournisseurs GetFournisseursFromIds(List<int> FournisseursIds) et dans la classe Marques la fonction Marques GetMarquesFromIds(List<int> MarqueIds).
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  3. #3
    Expert confirmé
    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 : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Entre temps, j'ai bien sûr continuer à réfléchir de mon côté (c'est dingue qu'on ne trouve quasi rien là-dessus sur le net) et je suis arrivé au code qui va suivre mais je ne suis pas convaincu. Qu'en pensez-vous ?

    Voici les classes Marque et Fournisseur de la couche BAL:
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    Public Class Marque
        Inherits ANTI_MALI_DTO.Marque
     
        Public Sub New(id As Integer, name As String)
            MyBase.New(id, name)
        End Sub
     
        Public Function GetFournisseurs() As List(Of Fournisseur)
            Return Fournisseur.SelectFournisseur(, Me.Id)
        End Function
     
        Public Function GetStores() As List(Of Store)
            Return Store.SelectStore(, , , Me.Id)
        End Function
     
        Public Function GetDemos() As List(Of Demo)
            Return Demo.SelectDemo()
        End Function
     
        Public Shared Function SelectMarque(Optional ByVal id As Integer = -1, Optional ByVal idFournisseur As Integer = -1) As List(Of Marque)
            Dim result As New List(Of Marque)
            For Each m As ANTI_MALI_DTO.Marque In ANTI_MALI_DAL.Marque.SelectMarque(id, idFournisseur)
                result.Add(New Marque(m.Id, m.Name))
            Next
            Return result
        End Function
    End Class
     
    Public Class Fournisseur
        Inherits ANTI_MALI_DTO.Fournisseur
     
        Public Sub New()
            MyBase.New()
        End Sub
     
        Public Sub New(id As Integer, name As String)
            MyBase.New(id, name)
        End Sub
     
        Public Function GetMarques() As List(Of Marque)
            Return Marque.SelectMarque(, Me.Id)
        End Function
     
        Public Shared Function SelectFournisseur(Optional ByVal id As Integer = -1, Optional ByVal idMarque As Integer = -1) As List(Of Fournisseur)
            Dim result As New List(Of Fournisseur)
            For Each f As ANTI_MALI_DTO.Fournisseur In ANTI_MALI_DAL.Fournisseur.SelectFournisseur(id, idMarque)
                result.Add(New Fournisseur(f.Id, f.Name))
            Next
            Return result
        End Function
    End Class
    Les classes Marque et Fournisseur de la couche DTO :
    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
    Public Class Marque
        Public Property Id As Integer
        Public Property Name As String
     
        Public Sub New(id As Integer, name As String)
            Me.Id = id
            Me.Name = name
        End Sub
     
    End Class
     
    Public Class Fournisseur
        Public Property Id As Integer
        Public Property Name As String
     
        Public Sub New()
        End Sub
     
        Public Sub New(id As Integer, name As String)
            Me.Id = id
            Me.Name = name
        End Sub
    End Class
    Et pour finir, les classes Marque et Fournisseur de la couche DAL :
    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
    Public Class Marque
     
        Public Shared Function SelectMarque(ByVal id As Integer, ByVal idFournisseur As Integer) As List(Of ANTI_MALI_DTO.Marque)
     
            Dim result As New List(Of ANTI_MALI_DTO.Marque)
     
            'accès DB et remplissage de la liste
     
            Return result
        End Function
    End Class
     
    Public Class Fournisseur
     
        Public Shared Function SelectFournisseur(id As Integer, idMarque As Integer) As List(Of ANTI_MALI_DTO.Fournisseur)
            Dim result As New List(Of ANTI_MALI_DTO.Fournisseur)
     
            'accès DB
     
            Return result
        End Function
    End Class
    A priori, ça fonctionne. Mais j'ai l'impression de faire plusieurs fois le boulot...
    Kropernic

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