Probleme d'Inheritance / Structuration du code
Bonjour,
Voici mon probleme. Je suppose qu'il est trivial pour quelqu un qui maitrise le jonglage entre classes, mais il ne l est pas pour moi ... :(
Dans une base de donnees, j ai des elements qui sont TOUS des noeuds. Or certains de ces noeuds sont des reservoirs et ont donc des attributs que les autres noeuds n'ont pas (par exemple une capacité de stockage d'eau), mais ont tous les attributs des noeuds.
C'est pourquoi, j ai crée une classe My_node avec tous les attributs des noeuds :
Code:
1 2 3 4 5 6 7 8 9 10
| Public Class My_node
Public node_id As Integer
Public type_id As Integer
Public name As String
Public X As Single
Public Y As Single
Public Water_company As String
Public WRZ As String
Public RWSM_type As String
End Class |
et une classe My_Reservoir qui inherite de ma classe My_node a laquelle j'ajoute les attributs specifiques a un reservoir (Capacity et Initial Storage):
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Public Class My_Reservoir
Inherits My_node
Public Capacity As Integer
Public Initial_Storage As Integer
Sub Fromnode(ByVal anode As My_node)
Me.name = anode.name
Me.node_id = anode.node_id
Me.RWSM_type = anode.RWSM_type
Me.type_id = anode.type_id
Me.Water_company = Me.Water_company
Me.WRZ = anode.WRZ
Me.X = anode.X
Me.Y = anode.Y
End Sub
End Class |
(Notez la Sub Fromnode car ma question porte sur ca)
De plus, chaque noeud (et donc aussi reservoir) est attribué à ce que j appelle une "water resource zone" (WRZ). qui est donc un groupe noeuds. D'ou Ma classe My_WRZ :
Code:
1 2 3 4 5 6 7 8 9
| Public Class My_WRZ
Public Water_company As String
Public WRZ As String
Public WRZ_Reservoir As New My_Reservoir
Public WRZ_Junction As New My_node
Public WRZ_WTW As New My_node
Public WRZ_Dembis As New My_node
Public WRZ_Dem As New My_node
End Class |
COmme vous pouvez le voir ci-dessus, une WRZ contient donc des noeuds classiques (My_node) et un reservoir (My_reservoir).
Vous suivez jusque la ? :aie:
Dans ma Forme (je connais pas le nom en francais sry), j'utilise 2 dictionnaires. Un pour mes noeuds et un pour Mes WRZ :
Code:
1 2
| Dim Dico_nodes As New Dictionary(Of Integer, My_node)
Dim Dico_WRZ As New Dictionary(Of String, My_WRZ) |
Ce que je souhaite faire est donc de lire les attributs de chaque noeud de ma base de données. Les ajouter a mon dictionnaire de noeuds, puis mettre a jour mon Dictionnaire de WRZ.
Le code que j utilise (et qui semble fonctionner) est le suivant:
Code:
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
| Dim SQLreader1 As SQLiteDataReader = SQLcommand1.ExecuteReader()
While SQLreader1.Read()
Dim Anode As New My_node
Anode.node_id = SQLreader1(0)
Anode.type_id = SQLreader1(2)
Anode.name = SQLreader1(3)
Anode.X = SQLreader1(5)
Anode.Y = SQLreader1(6)
Anode.Water_company = SQLreader1(7)
Anode.WRZ = SQLreader1(8)
Anode.RWSM_type = SQLreader1(9)
Dico_nodes.Add(Anode.node_id, Anode)
If Dico_WRZ.ContainsKey(Anode.WRZ) = False Then
Dim AWRZ As New My_WRZ
AWRZ.Water_company = Anode.Water_company
AWRZ.WRZ = Anode.WRZ
Dico_WRZ.Add(AWRZ.WRZ, AWRZ)
End If
If Anode.RWSM_type = "WRZ Reservoir" Then
Dico_WRZ(Anode.WRZ).WRZ_Reservoir.Fromnode(Dico_nodes(Anode.node_id))
ElseIf Anode.RWSM_type = "WRZ WTW" Then
Dico_WRZ(Anode.WRZ).WRZ_WTW = Dico_nodes(Anode.node_id)
ElseIf Anode.RWSM_type = "WRZ Junction" Then
Dico_WRZ(Anode.WRZ).WRZ_Junction = Dico_nodes(Anode.node_id)
ElseIf Anode.RWSM_type = "WRZ Dembis" Then
Dico_WRZ(Anode.WRZ).WRZ_Dembis = Dico_nodes(Anode.node_id)
ElseIf Anode.RWSM_type = "WRZ Dem" Then
Dico_WRZ(Anode.WRZ).WRZ_Dem = Dico_nodes(Anode.node_id)
End If
End While
SQLreader1.Close() |
Mon probleme est que je ne comprends pas pourquoi si mon noeud est un reservoir, je doive utiliser la ligne de code suivante sans pouvoir tout simplement dire que tel noeud est le reservoir de ma WRZ.
Code:
Dico_WRZ(Anode.WRZ).WRZ_Reservoir.Fromnode(Dico_nodes(Anode.node_id))
Je suis quasiment sur que ce que j ai ecris dans mon code est du bidouillage bancal, mais je n'arrive pas a mettre le doigt sur une solution plus "propre" ...
Merci.
Slumpy
reseau hydraulique,et dicos nodes.
bonjour Slumpy
Il me semble que ton souci de gestion de reseau hydraulique aurait gagne à etre analyse un peu plus.
Pourquoi heriter d'un noeud My_Node en creant un noeud specifique Reservoir (reservoir est un attribut de noeud d'ailleur comme junction,vanne dans ta bd etc....) et stocker tous les champs dans celui-ci.
Il suffit d'une association avec une prop referencant le noeud qui le contient (une petite adresse en memoire) car un reservoir est ......un noeud.
Par ailleurs la creation ou instanciation d'un My_Reservoir necessite au prealable celle d'un My_Node (pas de reservoir ....flottant dans le reseau).
Relativement au dico des zones il est bon mais peche par un petit defaut .
J'aurais prefere que chaque zone contiennent un Dico par type ou attribut de noeud(reservoir ,junction,vanne etc....) au lieu d'un class My_Node.
Dicos dont on a besoin pour classer et lister les differents types de noeuds du reseau existant.
Modification du code:
Code:
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
'sans changement
Public Class My_nodeBis
Public node_id As Integer
Public type_id As Integer
Public name As String
Public X As Single
Public Y As Single
Public Water_company As String
Public WRZ As String
Public RWSM_type As String
End Class
'Association au lieu d'heritage
Public Class My_ReservoirBis
Public Capacity As Integer
Public Initial_Storage As Integer
'prop avec reference sur noeud support
Private m_refnode As My_nodeBis
Public Sub New(ByVal objNode As My_nodeBis)
Me.m_refnode = objNode
End Sub
'a supprimer
'Sub Fromnode(ByVal objNode As My_nodeBis)
' Me.m_refnode = objNode
'End Sub
Public Property RefNode() As My_nodeBis
Get
Return m_refnode
End Get
Set(ByVal value As My_nodeBis)
m_refnode = value
End Set
End Property
End Class
'Dicos par attribut noeud
Public Class My_WRZBis
Public Water_company As String
Public WRZ As String
'Dico par type de noeud
Public WRZ_Reservoir As New Dictionary(Of String, My_ReservoirBis)
Public WRZ_WTW As New Dictionary(Of String, My_nodeBis)
Public WRZ_JunctionBis As New Dictionary(Of String, My_nodeBis)
Public WRZ_Dembis As New Dictionary(Of String, My_nodeBis)
Public WRZ_Dem As New Dictionary(Of String, My_nodeBis)
Public Sub New()
End Sub
End Class
Public Class Form2
Dim Dico_NodesBis As New Dictionary(Of Integer, My_nodeBis)
Dim Dico_WRZBis As New Dictionary(Of String, My_WRZBis)
Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim SQLreader1 As SqlClient.SqlDataReader = SQLcommand1.ExecuteReader()
While SQLreader1.Read()
Dim Anode As New My_nodeBis
Anode.node_id = SQLreader1(0)
Anode.type_id = SQLreader1(2)
Anode.name = SQLreader1(3)
Anode.X = SQLreader1(5)
Anode.Y = SQLreader1(6)
Anode.Water_company = SQLreader1(7)
Anode.WRZ = SQLreader1(8)
Anode.RWSM_type = SQLreader1(9)
Dico_NodesBis.Add(Anode.node_id, Anode)
Dim AWRZ As My_WRZBis
If Dico_WRZBis.ContainsKey(Anode.WRZ) = False Then
'nouvelle zone
AWRZ = New My_WRZBis
AWRZ.Water_company = Anode.Water_company
AWRZ.WRZ = Anode.WRZ
Dico_WRZBis.Add(AWRZ.WRZ, AWRZ)
End If
AWRZ = Dico_WRZBis(Anode.WRZ)
Select Case Anode.RWSM_type
Case "WRZ Reservoir"
Dim objReservoir As New My_ReservoirBis(Anode)
AWRZ.WRZ_Reservoir.Add(Anode.name, objReservoir)
Case "WRZ WTW"
AWRZ.WRZ_WTW.Add(Anode.name, Anode)
Case "WRZ Junction"
AWRZ.WRZ_JunctionBis.Add(Anode.name, Anode)
Case "WRZ Dembis"
AWRZ.WRZ_Dembis.Add(Anode.name, Anode)
Case "WRZ Dem"
AWRZ.WRZ_Dem.Add(Anode.name, Anode)
End Select
'If Anode.RWSM_type = "WRZ Reservoir" Then
' Dico_WRZ(Anode.WRZ).WRZ_Reservoir.Fromnode(Dico_nodes(Anode.node_id))
'ElseIf Anode.RWSM_type = "WRZ WTW" Then
' Dico_WRZ(Anode.WRZ).WRZ_WTW = Dico_nodes(Anode.node_id)
'ElseIf Anode.RWSM_type = "WRZ Junction" Then
' Dico_WRZ(Anode.WRZ).WRZ_Junction = Dico_nodes(Anode.node_id)
'ElseIf Anode.RWSM_type = "WRZ Dembis" Then
' Dico_WRZ(Anode.WRZ).WRZ_Dembis = Dico_nodes(Anode.node_id)
'ElseIf Anode.RWSM_type = "WRZ Dem" Then
' Dico_WRZ(Anode.WRZ).WRZ_Dem = Dico_nodes(Anode.node_id)
'End If
End While
SQLreader1.Close()
End Sub
'Iteration dans les differents Dicos
Private Sub btnIteration_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIteration.Click
'Find zone
Dim nameZone As String
Dim currentZone As My_WRZBis
For Each kv As KeyValuePair(Of String, My_WRZBis) In Dico_WRZBis
nameZone = kv.Key
currentZone = kv.Value
'Display namezone,type zone
MessageBox.Show(nameZone & currentZone.Water_company & currentZone.WRZ)
Next
'Find node
For Each currentNode As My_nodeBis In Dico_NodesBis.Values
nameZone = currentNode.WRZ
If Dico_WRZBis.ContainsKey(nameZone) Then
'Display reservoir
For Each xReservoir As My_ReservoirBis In Dico_WRZBis(nameZone).WRZ_Reservoir.Values
MessageBox.Show(xReservoir.RefNode.name & xReservoir.RefNode.WRZ & xReservoir.Capacity)
Next
'Display WRZ Junction
For Each xNodeJunction As My_nodeBis In Dico_WRZBis(nameZone).WRZ_JunctionBis.Values
MessageBox.Show(xNodeJunction.name & xNodeJunction.WRZ)
Next
End If
Next
End Sub
'Recherche d'un element dans les differents Dicos
Private Sub btnRecherche_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRecherche.Click
'Retrouve une zone dans Values avec la cle
Dim nameZone As String = "Zone1"
Dim currentZone As My_WRZBis = Dico_WRZBis(nameZone)
'Retrouve un noeud type "WRZ Reservoir" avec la cle "nom du noeud support"
Dim xnode1 As My_nodeBis
'Test d'existance de cle est -toujour indispensable- dans un dico.
If Dico_WRZBis(nameZone).WRZ_Reservoir.ContainsKey(xnode1.name) Then
Dim currentReservoir As My_ReservoirBis = Dico_WRZBis(nameZone).WRZ_Reservoir(xnode1.name)
End If
'Retrouve un noeud type "WRZ Junction" avec la cle "nom du noeud support"
Dim xnode2 As My_nodeBis
'Test d'existance de cle est -toujour indispensable- dans un dico.
If Dico_WRZBis(nameZone).WRZ_JunctionBis.ContainsKey(xnode2.name) Then
Dim currentNodeJunction As My_nodeBis = Dico_WRZBis(nameZone).WRZ_JunctionBis(xnode2.name)
End If
End Sub
End Class |
Quant au fromnode qui t'embete c'est en fait un simple sub New dans la classe My_Reservoir avec argument de type My_Node et un Property RefNode qui garde une reference dessus.
autres zones que des water resources
bonjour Slumpy
En complement à ce qu'as dit Don Quiche,on peut donner des orientations generales mais tout depend de l'objectif vise par ton application car toutes ces donnees, plus que probablement, vont servir à ma connaissance :
1/Soit une application de calcul technique de flots hydrauliques:
-proprietes fonctionnelles d'un node :debit injecte ou recu dans un node,debit sortant ,depassement de capacite d'un noeud pour un type reservoir ....etat manoeuvrable d'une node(closed ou opened),nombres de consommateurs connectes...etc...pointe de debit.....acte de maintenance.
-proprietes physique d'un node : dote de vanne,marque de vanne ,annee de fabrication etc.....
2/Soit un GIS hydraulique
-proprietes fonctionnelles :coord,localite,proprietaire........
-proprietes physique d'un node : dote de vanne,marque de vanne ,annee de fabrication etc.....
Ce qui fait que c'est l'analyse fonctionnelle de l'application-que nous n'avons pas - qui fera ressortir si on a besoin ,comme l'as dit Don Quiche, d'une classe Zone ancetre ayant des champs communs et d'une classe heritee pour chaque type.
Dans une zone d'un type donne un Dico par type de noeud est interessant si il ya plusieurs noeuds de ce type dans la dite zone(ce que j'avais compris implicitement de ta structure).
Sinon une reference sur le noeud support suffit(voir reservoir).
Par ailleurs au passage ,il s'agit la d'un reseau hydraulique dit de "Transport ou ossature principale" " et non de "Distribution ou ossature raccorde directement au consommateurs finaux " c'est pour cela que la "Water Resource " dans mon esprit me semblait etre une zone geographique apparente à une zone concede ou concession en francais ou il y avait le poste principal "Reservoir" de la Company raccordes à plusieurs noeuds ordinaires de consommateurs.
S'il s'agit de la representation d'un reseau au passage ,il manque "les arcs" ou canalisations represente par une classe paire de nodes(fromNode,ToNode) avec un dico des "Neighbours nodes" ou voisins d'un noeud.
Tout depend donc au final de la fonctionnalite du projet d'application et des conseils d'ordre general pourraient s'averer innopportun en l'absence de plus de details de ton part......
bon code................