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

C# Discussion :

Quel pattern utiliser ?


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 5
    Par défaut Quel pattern utiliser ?
    Bonjour,
    Dans l'attente du livre de pattern que j'ai commandé, j'aimerais avoir votre avis sur ce cas tout simple.

    J'ai une classe Channel qui fait différentes choses et lève différents événements (updated, reseted, inverted...)
    Ensuite, j'ai plusieurs classes, dérivant de Form, de UserControl, de diverses autres classes non graphiques (Measure, Buffer, Scan...) qui ont tous pour propriété un Channel.
    Donc pour toutes ces classes, je me retrouve avec un bout de code identique ressemblant à ça:
    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
     
    class ChannelForm : Form
    {
        Channel _channel = null;
        public Channel Channel
        {
            get {return _channel;}
            set {
                 Unregister();
                 Register(value);
           }
        }
     
        void Unregister()
        {
            if (_channel = null) return;
            _channel.updated -= new EventHandler(channel_updated);
            _channel.reseted -= new EventHandler(channel_reseted);
     
            FonctionUnregDiverses();
     
            _channel = null;
        }
     
        void Register(Channel c)
        {
            _channel.updated += new EventHandler(channel_updated);
            _channel.reseted += new EventHandler(channel_reseted);
     
           FonctionRegDiverses();
     
           _channel = c;
        }
     
     
        *****************************
        Reste de la classe, utilisant _channel
        *****************************
        ...
    }
    Comment faire pour enlever cette petite redondance de code ?
    Utiliser une classe statique, qui gère l'enregistrement du channel et de ces événements ?
    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
     
    public static class ChannelManager
    {
        public static void Register(Channel c, IChannelConsummer consummer)
        {
            Unregister(consummer);
     
            c.updated+=consummer.ChannelUpdated();
            c.reseted+=consummer.ChannelReseted();
            consummer.ChanneldAdded();
     
            ToChannels.Add(consummer, c);
        }
     
        public static void Unregister(IChannelConsummer consummer)
        {
            Channel ch = GetChannel(consummer);
            if ( ch == null) return;
     
            ch.updated-=consummer.ChannelUpdated();
            ch.reseted-=consummer.ChannelReseted();
            consummer.ChanneldRemoved();
     
            ToChannels.Remove(consummer);
         }
     
         static Dictionnary<IConsummer,Channel> ToChannels = new Dictionnary<IConsummer,Channel>();
         Channel GetChannel(IConsummer c)
         {
            Channel tmp;
            ToChannels.tryGetValue(c, ref tmp);
             return tmp;
         }
    }
     
    interface IChannelConsummer()
    {
     
          ChannelAdded();
          ChannelRemoved();
     
          ChannelUpdated();
          ChannelReseted();
     
    }
    Qu'en pensez-vous ?
    Est-ce un pattern connu ? Quel est son nom ?
    Merci

  2. #2
    Membre chevronné Avatar de MetalGeek
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 412
    Par défaut
    Salut,

    je verrais deux solutions.

    La première, tu peux utiliser les méthodes d'extension et une interface :
    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
     
    public interface IChannelContainer
    {
        Channel Channel
        {
            get;
            set;
        }
    }
     
    //dans une classe statique à part, genre 'ChannelContainerExtensions.cs'
     
    ...
     
    public static void SetChannel(this IChanelleContainer container, Channel channel)
    {
        Unregister(container);
        Register(container, channel);
    }
     
    private static void Unregister(IChannelContainer container)
        {
            if (container.Channel = null) return;
            container.Channel.updated -= new EventHandler(container.channel_updated);
            container.Channel.reseted -= new EventHandler(container.channel_reseted);
     
            FonctionUnregDiverses();
     
            container.Channel = null;
        }
     
        private static void Register(IChannelContainer container, Channel c)
        {
            channel.updated += new EventHandler(container.channel_updated);
            channel.reseted += new EventHandler(container.channel_reseted);
     
           FonctionRegDiverses();
     
           container.Channel = c;
        }
    ...
    Le souci n°1 de cette solution, c'est que rien n'empêche un autre code de valoriser la propriété Channel d'un élément sans passer par les méthodes d'extension (sans passer par 'monChannelContainer.SetChannel(c)').

    Du coup, je préfèrerais la solution suivante (tout dépend de ton code, de ce que tu peux modifier ou pas etc.) : utiliser la composition. Tu créés une classe ChannelContainer qui se charge d'implémenter les méthods Register() etc., et tes éléments auront un attribut ChannelContainer au lieu de Channel :

    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
     
    public sealed class ChannelContainer
    {
        private Channel _channel;
     
        public Channel Channel
        {
            get {return _channel;}
            set {
                 Unregister();
                 Register(value);
           }
        }
     
        void Unregister()
        {
            if (_channel = null) return;
            _channel.updated -= new EventHandler(channel_updated);
            _channel.reseted -= new EventHandler(channel_reseted);
     
            FonctionUnregDiverses();
     
            _channel = null;
        }
     
        void Register(Channel c)
        {
            _channel.updated += new EventHandler(channel_updated);
            _channel.reseted += new EventHandler(channel_reseted);
     
           FonctionRegDiverses();
     
           _channel = c;
        }    
    }
     
    //Exemple : à remplacer dans les classes qui utilisaient une propriété Channel
    public class Buffer
    {
        private readonly ChannelContainer _channelContainer = new ChannelContainer();
     
        public ChannelContainer ChannelContainer
        {
            get { return this._channelContainer; }
        }
    }
    Si jamais les corps des méthodes 'channel_updated' etc. dépendent des objets et sont différentes selon les cas (Buffer, UserControls etc), tu passes une référence à l'objet parent dans le constructeur de ChannelContainer :

    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
     
    public sealed class ChannelContainer
    {
       ...
     
       private IChannelUser _parent;
     
       public ChannelContainer(IChannelUser parent)
       {
            this._parent = parent;
        }
     
        void Register(Channel c)
        {
            _channel.updated += new EventHandler(this._parent.channel_updated);
            _channel.reseted += new EventHandler(this._parent.channel_reseted);
       ...
    }
     
    public interface IChannelUser
    {
        ChannelContainer ChannelContainer
        {
            get;
        }
     
        void channel_updated(object sender, EventArgs e);
        void channel_reseted(object sender, EventArgs e);
    }
     
    public class Buffer : IChannelUser
    {
        private readonly ChannelContainer _container;
     
       public Buffer()
       {
            this._container = new ChannelContainer(this);
       }
    }

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 5
    Par défaut
    Merci pour ta réponse.
    Cependant, je ne suis pas sûr que ça résolve mon problème!
    Ta solution n°2, de la composition est élégante, mais je dois créer une classe ChannelContainer pour chaque classe utilisant un channel, puisque les EventHandler seront différents !

    Ok, tu as mis à jour ton post et tu réponds à ma question!
    Parfait tout ça
    J'y étais presque celà dit, il aurait suffi que je pense à utiliser un continaer.
    merci

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Tu pourrais simplement faire hériter toutes tes forms d'une classe de base ChannelForm qui déclarerait la propriété Channel

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

Discussions similaires

  1. Design, Quel pattern utiliser ?
    Par omc24 dans le forum Débuter
    Réponses: 2
    Dernier message: 29/11/2010, 18h32
  2. Quel design pattern utiliser?
    Par spektrum dans le forum Développement Web en Java
    Réponses: 1
    Dernier message: 28/07/2010, 09h59
  3. Quel pattern utiliser pour changer les possibilités d'un objet
    Par lichman dans le forum Design Patterns
    Réponses: 4
    Dernier message: 05/10/2007, 14h02
  4. Réponses: 3
    Dernier message: 27/08/2003, 21h14
  5. Réponses: 2
    Dernier message: 11/07/2002, 08h31

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