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 :

Problème de conception (Design pattern ?) : création d'objets polymorphes


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 14
    Par défaut Problème de conception (Design pattern ?) : création d'objets polymorphes
    Bonjour,

    Je cherche à redévelopper une partie de mon code proprement qui ressemble plus ou moins à ç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 MA
    {
       ...
       protected MB b;
     
       public MA(Param TheParam)
       {
          ...
          if (Cond1Exécution(TheParam))
             b = new FB1;
          else if (Cond2Exécution(TheParam))
             b = new FB2;
          ...      
       }
       ...   
    }
     
    class FA1 : MA
    {
       private FB1 b1;
       ...
    }
     
    class FA2 : MA
    {
       private FB2 b2;
       ...
    }
     
    *****
    foreach(truc in trucs)
    {
       MA a = new MA(truc);
       if (a.b is FB1)
       {
          FA1 a1 = new FA1(truc);
          collection1.add(a1);
       }
       ...
    }
    Mon besoin est donc de créer des objets composés dont le type est connu qu'à l'exécution.
    Concernant l'utilisation de mes classes, je sais que j'aurais du utiliser l'instruction using (et implémenter Dispose()) et faire une copie plutôt que de reconstruire entièrement mon objet dérivé. Mais je pense que la conception elle-même est mauvaise et que j'aurais du employer un design pattern de construction.

    J'aurai donc besoin d'aide, svp, pour savoir lequel et comment l'implémenter.

  2. #2
    Membre émérite
    Homme Profil pro
    Développeur / architecte
    Inscrit en
    Juillet 2009
    Messages
    473
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur / architecte

    Informations forums :
    Inscription : Juillet 2009
    Messages : 473
    Par défaut
    Je dirai que ça ressemble fortement au design pattern fabrique abstraite.
    Je passerai ton constructeur
    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
     
    class MA
    {
     
       public static MA Create(Param TheParam)
       {
          ...
          if (Cond1Exécution(TheParam))
             return new FB1();
          else if (Cond2Exécution(TheParam))
             return new FB2();
          ...      
       }
       ...   
    }
    Après le reste est quasiment pareil. Par contre, en + je me débrouillerai pour avoir transformer les CondXExécution() en un seul qui renvoie un enum. Du coup ensuite ton if else if else if deviendarit un simple switch case...

  3. #3
    Membre émérite
    Avatar de dkmix
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    619
    Détails du profil
    Informations personnelles :
    Localisation : Jamaïque

    Informations forums :
    Inscription : Septembre 2007
    Messages : 619
    Par défaut
    Bonjour,
    Vous pouvez utiliser des classes génériques
    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
     
     public interface IB
        {
            void Action1();
        }
     
    public class A<T> where T : IB
        {
            protected T _b;
            public T B {get {return _b;} set {_b = value;}}
     
             public A(T b)
            {
                _b = b;
            }
        }
    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
     
    //Classes B réelles :
     public class B1 : IB
        {
            public void Action1()
            {
                throw new NotImplementedException();
            }
        }
     public class B2 : IB
        {
            public void Action1()
            {
                throw new NotImplementedException();
            }
        }
    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
     
    public class Factory
        {        
            public static A<IB> Create(Params args)
            {
                IB b;
                //check condition de creation de B1 ou B2
                if(Convert.ToBoolean(new Random().Next() % 2))
                {
                    b = new B1();
                }else
                {
                    b = new B2();
                }            
     
                return new A<IB>(b);
     
            }
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ..
       //nouvel objet A
       A<IB> monA = Factory.Create(mesParams);            
       //methode de l'interface IB
       monA.B.Action1();
    ..

  4. #4
    Membre chevronné Avatar de pascalCH
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Juillet 2006
    Messages
    188
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 188
    Par défaut AUtre solution : la Reflexion
    Bonjour,

    une autre solution - très souple - consiste à utiliser la Reflexion et les informations run-time.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    using System.Reflection;
     
        class MyClass
        {
            public Object Create(Type target)
            {
                object o;
     
                o = target.GetConstructor(Type.EmptyTypes).Invoke(new object[] { });
                return o;
            }        
        }
    La méthode Create attend un Type dont le constructeur par défaut va être identifié l'exécution.
    Il faut juste penser à caster l'objet retourné avec le on type.

  5. #5
    Membre averti
    Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 14
    Par défaut
    Bonjour,

    Merci beaucoup pour vos réponses, ça m'a aidé à réfléchir sur mon problème de conception.
    En fait, la classe MB et ses 2 dérivées sont des classes du framework auxquelles je fais correspondre ma classe MA et 3 classes dérivées, la 3e n'incluant pas de type MB. Celles-ci ont des champs, des propriétés et des (signatures de) méthodes différents.
    Donc, j'ai finalement utilisé une fabrique "simple" (Factory Method) :
    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
     
    static class MAFactory
    { 
       public static MA Create(Param TheParam)
       {
          MA product = null;
          ...
     
          try
          {
             ...
             if (Cond1Exécution(TheParam))
                product = new FA1();
             else if (Cond2Exécution(TheParam))
                product = new FA2();
             else
                product = new FA3();
          }
          catch(..)
          {...}
     
          return product;
       }
    }
    et j'ai mis l'instanciation des objets de type FB1 et FB2 à leur place, c.a.d. dans les constructeurs de FA1 et FA2.
    Pour l'utilisation, j'ai juste à caster la sortie de ma fabrique à l'aide d'un enum (@chrisdot et, éventuellement, d'un switch case ) que j'avais déjà implémenté. Dans mon premier post, j'avais mis "a.b is FB1" comme condition pour simplifier mais je doute que ça aurait fonctionné.

    PS: @dkmix et @pascalCH, même si vos propositions ne correspondaient pas exactement à mon besoin, elles sont intéressantes je les retiens.

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

Discussions similaires

  1. [Conception] Design pattern Memento
    Par olivier1978 dans le forum C++
    Réponses: 4
    Dernier message: 08/09/2007, 19h21
  2. [Conception] Design Pattern Observer Java
    Par jeb001 dans le forum Général Java
    Réponses: 4
    Dernier message: 02/05/2007, 23h43
  3. [Conception]Design Pattern Factory ?
    Par ®om dans le forum Logging
    Réponses: 8
    Dernier message: 13/09/2006, 10h20

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