OVH Cloud OVH Cloud

variable globale

14 réponses
Avatar
pierre
hum hum,
j'ai posé une question il y a 2 jours pour savoir comment avoir un dataset
commun à 2 forms**.
Le pb, C'est que je n'ai pas de dataadapter puisque je remplie mon dataset
par un fichier XML.
Un truc (entre autre:-)) que je ne comprends pas: il n'es pas possible
d'avoir une variable glogale dans mon projet?
Je la créé ds un formulaire, je l'instancie avec new, je l'utilise et mon
2eme formulaire l'utilise?
Ds ces cas la, pourquoi ne pas mettre mon dataset en variable globale?
pffff. Je vais bientot commencer à pleurer...

Merci à ceux qui peuvent me repondre.


**pour l'instant, je palie à ca en ecrivant le fichier XML apres les maj et
en le chargeant à l'ouverture du 2eme formulaire.
Ca marche pas mal mais j'ai impression d'eclater les mouches à la dynamite!

4 réponses

1 2
Avatar
Bruno Jouhier [MVP]
"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de
news: OQagrTx$
Salut Pierre! :O)

Ds ces cas la, pourquoi ne pas mettre mon dataset en variable globale?
pffff. Je vais bientot commencer à pleurer...



Les variables globales ne respete pas le concept OO et reste en mémoire
tout
le long du processus ce qui n'est pas toujours souhaitable...



Non! La plupart des langages OO ont des variables globales (static, shared,
...).
Et ces variables ont leur utilité, par exemple:

* Pour partager des données entre plusieurs threads (par exemple un cache de
données dans un serveur).

* Pour mettre en place un contexte qui influence toutes les opérations, par
exemple la "culture" du thread en cours, sa "timezone". Sans variable
globale, on est obligé de passer ce context dans toutes les APIs, ce qui est
lourd, inefficace, illisible, etc.

Les variables globales ne sont donc pas une chose à bannir absolument en
POO. Il faut juste éviter de les utiliser quand on peut faire sans, mais il
faut aussi savoir faire avec.

Aussi, les variables en elles-mêmes utilisent peu de mémoire (4 octets en
général) et le fait qu'elles restent en mémoire n'est pas gênant en général.
Ce qui prend de la place en mémoire, ce sont les objets référencés par ces
variables (et là, ça peut poser problème).

Bruno.





Voici une bonne pratique de programmation à appliquer dans un cas
semblable.
'***
' Form1
Option Explicit On

Imports System.Data
Imports System.Data.SqlClient

Public Class Form1
Inherits System.Windows.Forms.Form

Private _ds As DataSet

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
Friend WithEvents Button1 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(120, 112)
Me.Button1.Name = "Button1"
Me.Button1.TabIndex = 0
Me.Button1.Text = "Button1"
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(Me.Button1)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load

InitDataSource()
Button1.Text = "Form2"

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim dr As DataRow

If (EditDataSource(_ds)) Then
Console.WriteLine("le dataset à été modifié. Il contient
maintenant {0} ligne(s)", _ds.Tables(0).Rows.Count)
End If

End Sub

Private Sub InitDataSource()

Dim dt As DataTable = New DataTable("MaTable")
dt.Columns.Add("ID", GetType(Int32))
dt.Columns.Add("Prenom", GetType(String))

_ds = New DataSet
_ds.Tables.Add(dt)

End Sub

Private Function EditDataSource(ByRef ds As DataSet) As Boolean

Dim frm As Form2
Dim bRet As Boolean

' on passe le dataset en entrée.. note qu'on
' aurait pu le faire en mode "constructeur" (New Form2(_ds))
frm = New Form2
frm.DataSource = ds
frm.ShowDialog(Me)
If (frm.DialogResult = DialogResult.OK) Then
' des modifs ont été effectués, on peut
' donc réaffecté notre DataSet..
'ds = frm.DataSource
bRet = True
End If
frm.Close()

Return bRet

End Function

End Class
'***
' Form2
Option Explicit On

Imports System.Data
Imports System.Data.SqlClient

Public Class Form2
Inherits System.Windows.Forms.Form

Private _ds As DataSet

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Label1 As System.Windows.Forms.Label
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.Label1 = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'Button1
'
Me.Button1.DialogResult = System.Windows.Forms.DialogResult.OK
Me.Button1.Location = New System.Drawing.Point(128, 112)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(88, 24)
Me.Button1.TabIndex = 0
Me.Button1.Text = "&Ok"
'
'Button2
'
Me.Button2.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.Button2.Location = New System.Drawing.Point(32, 112)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(80, 24)
Me.Button2.TabIndex = 1
Me.Button2.Text = "&Annuler"
'
'Label1
'
Me.Label1.Location = New System.Drawing.Point(16, 40)
Me.Label1.Name = "Label1"
Me.Label1.Size = New System.Drawing.Size(216, 48)
Me.Label1.TabIndex = 2
Me.Label1.Text = "Lors de l'ouverture de page, le dataset à été
modifié. Appuyer sur Ok si vous sou" & _
"haitez conserver ces changements."
'
'Form2
'
Me.AcceptButton = Me.Button1
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.CancelButton = Me.Button2
Me.ClientSize = New System.Drawing.Size(240, 158)
Me.Controls.Add(Me.Label1)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.Name = "Form2"
Me.Text = "Form2"
Me.ResumeLayout(False)

End Sub

#End Region

' Permet d'échanger le DataSet avec les autres objets
Public Property DataSource() As DataSet
Get
Return _ds
End Get
Set(ByVal Value As DataSet)
_ds = Value
End Set
End Property

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
' ici on modifie le dataset pour le test..
' on aurait pu le branché à une DataGrid
' et laissé l'utilisateur faire les modifs
ChangeDataSource()
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
_ds.AcceptChanges()
Me.Hide()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
_ds.RejectChanges()
Me.Hide()
End Sub

Private Sub ChangeDataSource()
Dim dt As DataTable
If ((Not _ds Is Nothing) AndAlso (_ds.Tables.Count > 0) AndAlso
(_ds.Tables(0).Columns.Count = 2)) Then
dt = _ds.Tables(0)
dt.Rows.Add(New Object() {1, "yan"})
dt.Rows.Add(New Object() {2, "nick"})
dt.Rows.Add(New Object() {3, "pat"})
dt.Rows.Add(New Object() {4, "mario"})
End If
End Sub

End Class
'***


Note que dans le formulaire Form2, j'ai dû modifier les propriétés
suivantes
afin de bien détecter l'action qui a été fait par l'utilisateur :

Button1.DialogResult = DialogResult.OK
Button2.DialogResult = DialogResult.Cancel
Me.AcceptButton = Me.Button1
Me.CancelButton = Me.Button2

--
Cordialement
Yanick
MVP pour Visual Basic




Avatar
Patrick Philippot
Bruno Jouhier [MVP] wrote:
Non! La plupart des langages OO ont des variables globales (static,
shared, ...).
Et ces variables ont leur utilité, par exemple:



Salut Bruno,

C'est une question de mots mais les mots ont ici leur importance. Il est
vrai qu'une méthode ou une propriété shared ou static se comportent
comme si elles étaient globales. Il y a quand même une nuance de taille,
c'est qu'elles sont nécessairement attachées à une classe et pour moi,
cela change tout car cela donne une indication claire sur leur domaine
d'utilisation.

Le problème des variables et fonctions globales au sens strict du terme,
c'est qu'elles ne sont sémantiquement rattachées à rien de particulier
et c'est ce qui amène les confusions que l'on veut justement éviter. Le
fait d'être obligé de qualifier le nom de la variable ou de la méthode
globale avec un nom de classe fournit un avertissement immédiat en cas
d'utilisation inadéquate. C'est particuliètement vrai pour les
énumérations par exemple : une constante symbolique ne peut plus être
utilisée hors contexte sauf si on fait vraiment n'importe quoi.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Bruno Jouhier [MVP]
"Patrick Philippot" a écrit dans le
message de news:
Bruno Jouhier [MVP] wrote:
Non! La plupart des langages OO ont des variables globales (static,
shared, ...).
Et ces variables ont leur utilité, par exemple:



Salut Bruno,

C'est une question de mots mais les mots ont ici leur importance. Il est
vrai qu'une méthode ou une propriété shared ou static se comportent comme
si elles étaient globales. Il y a quand même une nuance de taille, c'est
qu'elles sont nécessairement attachées à une classe et pour moi, cela
change tout car cela donne une indication claire sur leur domaine
d'utilisation.

Le problème des variables et fonctions globales au sens strict du terme,
c'est qu'elles ne sont sémantiquement rattachées à rien de particulier et
c'est ce qui amène les confusions que l'on veut justement éviter. Le fait
d'être obligé de qualifier le nom de la variable ou de la méthode globale
avec un nom de classe fournit un avertissement immédiat en cas
d'utilisation inadéquate. C'est particuliètement vrai pour les
énumérations par exemple : une constante symbolique ne peut plus être
utilisée hors contexte sauf si on fait vraiment n'importe quoi.



D'accord. Le point qui me gênait, c'était l'affirmation que "les variables
globales ne respectent pas le concept OO".

C'est vrai d'un point de vue "syntaxique". En Java ou C#, il n'y a plus de
variables globales au sens strict, il n'y a que des variables statiques
(shared en VB) et il faut les qualifier avec un nom de classe pour y accéder
(ce qui est une excellente chose).

Mais si on oublie la syntaxe et qu'on se concentre sur la sémantique, les
variables statiques/shared ont leur utilité en POO.

Bruno.


--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr



Avatar
Zoury
Je suis entièrement d'accord avec toutes les précisions que vous avez
apportées à mon
message. Je parlais bien des variables déclarées publiques dans un module.
Les variables Shared étant bien entendu très utiles et même indispensable
d'un point vu logique. Il serait, par exemple, illogique de devoir instancié
un objet de Type Process afin d'appeler la méthodes GetProcesses() qui elle
renvoit tous les processus actifs du système...

--
Cordialement
Yanick
MVP pour Visual Basic

"Bruno Jouhier [MVP]" a écrit dans le message de
news:%

"Patrick Philippot" a écrit dans le
message de news:
> Bruno Jouhier [MVP] wrote:
>> Non! La plupart des langages OO ont des variables globales (static,
>> shared, ...).
>> Et ces variables ont leur utilité, par exemple:
>
> Salut Bruno,
>
> C'est une question de mots mais les mots ont ici leur importance. Il est
> vrai qu'une méthode ou une propriété shared ou static se comportent


comme
> si elles étaient globales. Il y a quand même une nuance de taille, c'est
> qu'elles sont nécessairement attachées à une classe et pour moi, cela
> change tout car cela donne une indication claire sur leur domaine
> d'utilisation.
>
> Le problème des variables et fonctions globales au sens strict du terme,
> c'est qu'elles ne sont sémantiquement rattachées à rien de particulier


et
> c'est ce qui amène les confusions que l'on veut justement éviter. Le


fait
> d'être obligé de qualifier le nom de la variable ou de la méthode


globale
> avec un nom de classe fournit un avertissement immédiat en cas
> d'utilisation inadéquate. C'est particuliètement vrai pour les
> énumérations par exemple : une constante symbolique ne peut plus être
> utilisée hors contexte sauf si on fait vraiment n'importe quoi.

D'accord. Le point qui me gênait, c'était l'affirmation que "les variables
globales ne respectent pas le concept OO".

C'est vrai d'un point de vue "syntaxique". En Java ou C#, il n'y a plus de
variables globales au sens strict, il n'y a que des variables statiques
(shared en VB) et il faut les qualifier avec un nom de classe pour y


accéder
(ce qui est une excellente chose).

Mais si on oublie la syntaxe et qu'on se concentre sur la sémantique, les
variables statiques/shared ont leur utilité en POO.

Bruno.

>
> --
> Patrick Philippot - Microsoft MVP
> MainSoft Consulting Services
> www.mainsoft.fr
>




1 2