OVH Cloud OVH Cloud

question de type "bonne pratique objet"

5 réponses
Avatar
Thierry Fierville
Bonjour,

j'aimerais avoir votre avis sur la question suivante : j'ai d'un côté mon
IHM classique de type Winform et de l'autre une dll contenant un ensemble de
classes regroupées en packages.
Je veux que mon IHM affiche la progression de mon traitement (par exemple,
afficher dans un scrollbar le pourcentage de fichier parcouru ou le
pourcentage d'octets téléchargés) mais ce traitement s'effectue dans ma dll,
au fin fond d'une classe bien "à l'abri" dans son package (découplage
oblige).
D'un point de vue architecture objet, quelle est la meilleure pratique pour
propager ce genre d'information d'une classe fonctionnelle vers une IHM ?

5 réponses

Avatar
Pascal Belaud [MS]
Salut,

Le mieux est de déclarer un delegate/évenement dans ta classe et que l'IHM
s'abonne ou pas à celui-ci. Il existe une best practice pour ceci. Voici un
exemple (je pars de la copie d'un fichier)

using System;

namespace Library {

public delegate void FileCopyProgressEventHandler(object sender,
FileCopyProgressArgs e);

public class MaClasse {

public event FileCopyProgressEventHandler FileCopyProgress = null;

public void FileCopy(string originalFile, string destinationFile) {

// Je simule une boucle sur la taille du fichier
for (int i = 0; i < 1000000; i++) {

if (FileCopyProgress != null) {

FileCopyProgress(this, new FileCopyProgressArgs(Convert.ToSingle(i) /
Convert.ToSingle(1000000)));
}
}
}
}

public class FileCopyProgressArgs : EventArgs {

private float pourcentage = 0;
public float Pourcentage {

get {

return(this.pourcentage);
}
}

public FileCopyProgressArgs(float pourcentage) {

this.pourcentage = pourcentage;

}
}
}

namespace IHM {

public class MainClass {

public static void Main() {

Library.MaClasse maClasse = new Library.MaClasse();
maClasse.FileCopyProgress += new
Library.FileCopyProgressEventHandler(maClasse_FileCopyProgress);

maClasse.FileCopy("OriginalFile", "DestinationFile");

Console.ReadLine();
}

public static void maClasse_FileCopyProgress(object sender,
Library.FileCopyProgressArgs e) {

Console.WriteLine(e.Pourcentage.ToString("##0.00%"));
}
}
}

A bientôt,

--
Pascal Belaud - Microsoft France
OlyMars: SQL Server Centric .NET Code Generator

http://www.microsoft.com/france/msdn/olymars
http://www.olymars.net/latest.zip (interim build)
http://blogs.msdn.com/olymars
"Thierry Fierville" wrote in message
news:
Bonjour,

j'aimerais avoir votre avis sur la question suivante : j'ai d'un côté mon
IHM classique de type Winform et de l'autre une dll contenant un ensemble


de
classes regroupées en packages.
Je veux que mon IHM affiche la progression de mon traitement (par exemple,
afficher dans un scrollbar le pourcentage de fichier parcouru ou le
pourcentage d'octets téléchargés) mais ce traitement s'effectue dans ma


dll,
au fin fond d'une classe bien "à l'abri" dans son package (découplage
oblige).
D'un point de vue architecture objet, quelle est la meilleure pratique


pour
propager ce genre d'information d'une classe fonctionnelle vers une IHM ?




Avatar
Thierry Fierville
Ok, merci pour ta réponse détaillée qui confirme ce que je supposais être la
solution, c'est à dire un delegate.

Maintenant, admettons que je doive à la fois abonner l'IHM (pour le
progressbar) et un autre objet de la classe toto au même événement pour que,
d'un côté, l'IHM actualise la progression et que, de l'aute côté, la classe
toto fasse un traitement lambda.
La solution que j'ai trouvé consiste à rendre l'événement static mais ça
pose évidemment un problème si on veut utiliser plusieurs instances
différentes de la classe MaClasse (déclarant le delegate) pour des
traitements différents, par exemple en multithread ou par exemple si dans un
cas on veut que l'IHM réagisse mais pas dans un autre cas.

Je peux par exemple avoir besoin d'une classe de recherche de fichiers
déclarant un event pour lequel l'IHM affiche une progressbar, mais dans un
autre cas, avoir une classe utilisant cette même classe de recherche de
fichiers pour des besoins internes sans que l'IHM n'ait à réagir.

Quelle alternative au static dans ce cas là ?

"Pascal Belaud [MS]" wrote in message
news:uA%23E$
Salut,

Le mieux est de déclarer un delegate/évenement dans ta classe et que l'IHM
s'abonne ou pas à celui-ci. Il existe une best practice pour ceci. Voici


un
exemple (je pars de la copie d'un fichier)

using System;

namespace Library {

public delegate void FileCopyProgressEventHandler(object sender,
FileCopyProgressArgs e);

public class MaClasse {

public event FileCopyProgressEventHandler FileCopyProgress = null;

public void FileCopy(string originalFile, string destinationFile) {

// Je simule une boucle sur la taille du fichier
for (int i = 0; i < 1000000; i++) {

if (FileCopyProgress != null) {

FileCopyProgress(this, new FileCopyProgressArgs(Convert.ToSingle(i) /
Convert.ToSingle(1000000)));
}
}
}
}

public class FileCopyProgressArgs : EventArgs {

private float pourcentage = 0;
public float Pourcentage {

get {

return(this.pourcentage);
}
}

public FileCopyProgressArgs(float pourcentage) {

this.pourcentage = pourcentage;

}
}
}

namespace IHM {

public class MainClass {

public static void Main() {

Library.MaClasse maClasse = new Library.MaClasse();
maClasse.FileCopyProgress += new
Library.FileCopyProgressEventHandler(maClasse_FileCopyProgress);

maClasse.FileCopy("OriginalFile", "DestinationFile");

Console.ReadLine();
}

public static void maClasse_FileCopyProgress(object sender,
Library.FileCopyProgressArgs e) {

Console.WriteLine(e.Pourcentage.ToString("##0.00%"));
}
}
}

A bientôt,

--
Pascal Belaud - Microsoft France
OlyMars: SQL Server Centric .NET Code Generator

http://www.microsoft.com/france/msdn/olymars
http://www.olymars.net/latest.zip (interim build)
http://blogs.msdn.com/olymars
"Thierry Fierville" wrote in message
news:
> Bonjour,
>
> j'aimerais avoir votre avis sur la question suivante : j'ai d'un côté


mon
> IHM classique de type Winform et de l'autre une dll contenant un


ensemble
de
> classes regroupées en packages.
> Je veux que mon IHM affiche la progression de mon traitement (par


exemple,
> afficher dans un scrollbar le pourcentage de fichier parcouru ou le
> pourcentage d'octets téléchargés) mais ce traitement s'effectue dans ma
dll,
> au fin fond d'une classe bien "à l'abri" dans son package (découplage
> oblige).
> D'un point de vue architecture objet, quelle est la meilleure pratique
pour
> propager ce genre d'information d'une classe fonctionnelle vers une IHM


?
>
>




Avatar
Bismark Prods
Bonsoir,

Il me semble que cela ne pose pas tant de problème que vous semblez en
soulever. Toutes les classes qui le désire peuvent s'abonner au meme
événement (grâce au délégué). Et ensuite c'est un affaire de s'abonner ou
non si on veut ou non que l'événement soit géré.

Je ne suis pas sur de bien comprendre ou se situe précisément votre embarras
?

Bismark

"Thierry Fierville" a écrit dans le message de
news:
Ok, merci pour ta réponse détaillée qui confirme ce que je supposais être


la
solution, c'est à dire un delegate.

Maintenant, admettons que je doive à la fois abonner l'IHM (pour le
progressbar) et un autre objet de la classe toto au même événement pour


que,
d'un côté, l'IHM actualise la progression et que, de l'aute côté, la


classe
toto fasse un traitement lambda.
La solution que j'ai trouvé consiste à rendre l'événement static mais ça
pose évidemment un problème si on veut utiliser plusieurs instances
différentes de la classe MaClasse (déclarant le delegate) pour des
traitements différents, par exemple en multithread ou par exemple si dans


un
cas on veut que l'IHM réagisse mais pas dans un autre cas.

Je peux par exemple avoir besoin d'une classe de recherche de fichiers
déclarant un event pour lequel l'IHM affiche une progressbar, mais dans un
autre cas, avoir une classe utilisant cette même classe de recherche de
fichiers pour des besoins internes sans que l'IHM n'ait à réagir.

Quelle alternative au static dans ce cas là ?

"Pascal Belaud [MS]" wrote in message
news:uA%23E$
> Salut,
>
> Le mieux est de déclarer un delegate/évenement dans ta classe et que


l'IHM
> s'abonne ou pas à celui-ci. Il existe une best practice pour ceci. Voici
un
> exemple (je pars de la copie d'un fichier)
>
> using System;
>
> namespace Library {
>
> public delegate void FileCopyProgressEventHandler(object sender,
> FileCopyProgressArgs e);
>
> public class MaClasse {
>
> public event FileCopyProgressEventHandler FileCopyProgress = null;
>
> public void FileCopy(string originalFile, string destinationFile) {
>
> // Je simule une boucle sur la taille du fichier
> for (int i = 0; i < 1000000; i++) {
>
> if (FileCopyProgress != null) {
>
> FileCopyProgress(this, new FileCopyProgressArgs(Convert.ToSingle(i)


/
> Convert.ToSingle(1000000)));
> }
> }
> }
> }
>
> public class FileCopyProgressArgs : EventArgs {
>
> private float pourcentage = 0;
> public float Pourcentage {
>
> get {
>
> return(this.pourcentage);
> }
> }
>
> public FileCopyProgressArgs(float pourcentage) {
>
> this.pourcentage = pourcentage;
>
> }
> }
> }
>
> namespace IHM {
>
> public class MainClass {
>
> public static void Main() {
>
> Library.MaClasse maClasse = new Library.MaClasse();
> maClasse.FileCopyProgress += new
> Library.FileCopyProgressEventHandler(maClasse_FileCopyProgress);
>
> maClasse.FileCopy("OriginalFile", "DestinationFile");
>
> Console.ReadLine();
> }
>
> public static void maClasse_FileCopyProgress(object sender,
> Library.FileCopyProgressArgs e) {
>
> Console.WriteLine(e.Pourcentage.ToString("##0.00%"));
> }
> }
> }
>
> A bientôt,
>
> --
> Pascal Belaud - Microsoft France
> OlyMars: SQL Server Centric .NET Code Generator
>
> http://www.microsoft.com/france/msdn/olymars
> http://www.olymars.net/latest.zip (interim build)
> http://blogs.msdn.com/olymars
> "Thierry Fierville" wrote in message
> news:
> > Bonjour,
> >
> > j'aimerais avoir votre avis sur la question suivante : j'ai d'un côté
mon
> > IHM classique de type Winform et de l'autre une dll contenant un
ensemble
> de
> > classes regroupées en packages.
> > Je veux que mon IHM affiche la progression de mon traitement (par
exemple,
> > afficher dans un scrollbar le pourcentage de fichier parcouru ou le
> > pourcentage d'octets téléchargés) mais ce traitement s'effectue dans


ma
> dll,
> > au fin fond d'une classe bien "à l'abri" dans son package (découplage
> > oblige).
> > D'un point de vue architecture objet, quelle est la meilleure pratique
> pour
> > propager ce genre d'information d'une classe fonctionnelle vers une


IHM
?
> >
> >
>
>




Avatar
Ambassadeur Kosh
pour appuyer la réponse de Bismark, avez vous remarqué que l'abonnement
s'effecute avec += et non =. c'est en Delphi et en BCB qu'on affectait un
event. et, frequement, le code des handler memorisait l'ancien handler et
chainait les appels. donc aujourd'hui vous n'avez plus ce souci

essayez ça, vous verrez :
this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);

this.menuItem2.Click += new System.EventHandler(this.menuItem3_Click);
Avatar
Pascal Belaud [MS]
Salut,

Juste pour te dire que j'ai écrit un post dans mon blog suite à ta question,
histoire de garder une trace écrite de la réponse:
http://blogs.microsoft.fr/pascalbe/archive/2004/09/21/227.aspx

A bientôt,

--
Pascal Belaud - Microsoft France
OlyMars: SQL Server Centric .NET Code Generator

http://www.microsoft.com/france/msdn/olymars
http://www.olymars.net/latest.zip (interim build)
http://blogs.msdn.com/olymars


"Thierry Fierville" wrote in message
news:
Bonjour,

j'aimerais avoir votre avis sur la question suivante : j'ai d'un côté mon
IHM classique de type Winform et de l'autre une dll contenant un ensemble


de
classes regroupées en packages.
Je veux que mon IHM affiche la progression de mon traitement (par exemple,
afficher dans un scrollbar le pourcentage de fichier parcouru ou le
pourcentage d'octets téléchargés) mais ce traitement s'effectue dans ma


dll,
au fin fond d'une classe bien "à l'abri" dans son package (découplage
oblige).
D'un point de vue architecture objet, quelle est la meilleure pratique


pour
propager ce genre d'information d'une classe fonctionnelle vers une IHM ?