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 :

Hériter d'un champ, statique pour la classe qui hérite mais pas pour celle de base ?


Sujet :

C#

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Points : 909
    Points
    909
    Par défaut Hériter d'un champ, statique pour la classe qui hérite mais pas pour celle de base ?
    J'ai besoin de conseils pour la conception de ma librairie. Explications :

    Je veux développer une librairie contenant une classe abstraite - appelons-la LinkedObject - destinée à être "implémentée" par d'autres utilisateurs, dans leurs propres DLL. Enfin, par "implémenter" je veux dire qu'on doit pouvoir écrire une classe qui en hérite. (pbmes de vocabulaire...)
    Jusque là pas de soucis.

    Je voudrais de plus que chaque type défini par l'utilisateur de ma librairie et héritant de LinkedObject (par exemple une classe SpecificObject) puisse être relié à une certaine instance d'une certaine classe - appelons-la MDA.
    Ce qui revient à dire que je veux que la classe SpecificObject possède un champ statique de type MDA.

    Cependant, je ne veux pas que la charge de définir le champ statique revienne à l'utilisateur de ma librairie. D'autant que je compte me servir de ce champ dans les méthodes de ma classe abstraite.
    Il faudrait donc que je puisse le définir, moi, dans ma classe abstraite LinkedObject.
    Mon problème : comment faire pour que la valeur de ce champ puisse être à la fois :
    - différente pour chaque type héritant de ma classe
    - identique pour chaque instance d'un certain type, c'est-à-dire "statique" vis-à-vis de chaque type héritant de ma classe*


    Je récapépète de façon plus visuelle :

    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
    namespace maDLL // oui je sais DLL et namespace c'est différent mais comme ça c'est plus clair
    {
    	public abstract class LinkedObject
    	{
    		static MDA champProblematique;
    	}
    }
     
    namespace codeDeLUtilisateurDeMaDLL
    {
    	public class SpecificObject : LinkedObject
    	{
    		public static void Initialize(MDA champ)
    		{
    			SpecificObject.champProblematique = champ;
    		}
    	}
     
    	public class AnotherSpecificObject : LinkedObject
    	{
    		public static void Initialize(MDA champ)
    		{
    			AnotherSpecificObject.champProblematique = champ;
    		}
    	}
     
    }
    Code évidemment faux, mais ce que je voudrais c'est qu'en appelant SpecificObject.Initialize(uneInstanceDeMDA) et AnotherSpecificObject.Initialize(uneAutreInstanceDeMDA), les deux types différents soient liés à deux instances différentes de MDA.
    En tapant ça, je me rends compte d'ailleurs que ça serait bien si je pouvais implémenter Initialize à l'intérieur de ma classe abstraite...


    Voilà.
    J'ai essayé de chercher un design pattern ressemblant à ce type de problème mais je n'ai rien trouvé qui m'inspire...
    Donc si quelqu'un a une idée ce serait trèèès gentil de m'aider.
    Merci à tous ceux qui auront pris du temps pour lire tout ça et essayer de me comprendre !

  2. #2
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Pour moi ça ressemble à un Multiton (extension du Singleton)... Est ce que quelqu'un peut confirmer ?

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Points : 909
    Points
    909
    Par défaut
    J'ai googlé "Multiton"... ce qui donne quelque chose du genre :
    Stocker dans LinkedObject une liste statique de couples (type;instanceDeMDA) en utilisant le Type comme clé pour s'assurer que chaque type est lié à une seule instance...

    Ça peut marcher, j'essaie ça demain (j'ai pas mes outils de développement ici...)

  4. #4
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Citation Envoyé par Astartee
    J'ai googlé "Multiton"... ce qui donne quelque chose du genre :
    Stocker dans LinkedObject une liste statique de couples (type;instanceDeMDA) en utilisant le Type comme clé pour s'assurer que chaque type est lié à une seule instance...

    Ça peut marcher, j'essaie ça demain (j'ai pas mes outils de développement ici...)
    Oui c'est effectivement ce à quoi m'a fait penser ta description. J'espère que ça pourra t'aider à résourdre ton problème.

  5. #5
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    Je te remercie Astartee pour la qualité de la question.

    Je pense pas que tu n'as pas besoin d'un pattern pour résoudre ton probleme. Voici ce que je te propose :

    Code C# : 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
     
     public abstract class LinkedObject
        {
            private MDA champProblematique;
     
            public LinkedObject(MDA champ)
            {
                this.champProblematique = champ;
            }
        }
     
     
     
        public class SpecificObject : LinkedObject
        {
            private static MDA myMDA = null;
     
            public static void Initialize(MDA champ)
            {
                myMDA=champ;
            }
     
            public SpecificObject()
                : base(myMDA)
            {
     
            }
        }
     
        public class AnotherSpecificObject : LinkedObject
        {
            private static MDA myMDA = null;
     
            public static void Initialize(MDA champ)
            {
                myMDA=champ;
            }
     
            public AnotherSpecificObject():base(myMDA)
            {
     
            }
        }

    Le probleme de ce code est que t'es obligé d'appeler Initialize avant le construction de tes objets.

    Si tu insiste sur les DP. Je pense que tu peux utiliser une simple Factory qui permet de construire tes objets MDA et de vérifier leur univité en fonction des SpecifiedObject.

  6. #6
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Citation Envoyé par mehdi_tn
    Si tu insiste sur les DP. Je pense que tu peux utiliser une simple Factory qui permet de construire tes objets MDA et de vérifier leur univité en fonction des SpecifiedObject.
    C'est pas loin d'être un multiton, ce que tu propose là

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Points : 909
    Points
    909
    Par défaut
    Citation Envoyé par mehdi_tn
    Je te remercie Astartee pour la qualité de la question
    Bah euh de rien

    Par contre ta solution ne me convient pas vraiment, puisqu'elle suppose qu'on écrive du code dans les classes qui héritent de ma classe abstraite. Or ces classes sont censées être créées par l'utilisateur de ma librairie, pas par moi, et il est un peu lourd de l'obliger à copier du code pour pouvoir utiliser mes classes !


    Solution que je viens d'écrire et de tester (j'ai remplacé mon type MDA par un int pour ne pas me faire ch** plus que ç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
    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
    public abstract class LinkedObject
    {
    	private static Hashtable instances = new Hashtable();
    	private int champProblematique;
     
    	public static void Initialize(Type type, int champ)
    	{
    		if (instances.ContainsKey(type))
    		{
    			instances[type] = champ;
    		}
    		else
    		{
    			instances.Add(type, champ);
    		}
    	}
     
    	public LinkedObject()
    	{
    		if (!instances.Contains(this.GetType()))
    		{
    			throw new Exception("This type has not been initialized.");
    		}
    		else
    		{
    			this.champProblematique = (int)instances[this.GetType()];
    		}
    	}
    }
     
    public class SpecificObject : LinkedObject
    {
    	public SpecificObject()
    	{
    	}
    }
     
    public class AnotherSpecificObject : LinkedObject
    {
    	public AnotherSpecificObject()
    	{
    	}
    }
     
    public class YetAnotherSpecificObject : LinkedObject
    {
    	public YetAnotherSpecificObject()
    	{
    	}
    }
     
    static class Program
    {
    	static void Main()
    	{
    		LinkedObject.Initialize(typeof(SpecificObject), 1);
    		LinkedObject.Initialize(typeof(AnotherSpecificObject), 3);
     
    		SpecificObject inst1 = new SpecificObject(); // inst1.champProblematique = 1
    		SpecificObject inst2 = new SpecificObject(); // inst2.champProblematique = 1
    		SpecificObject inst3 = new SpecificObject(); // inst3.champProblematique = 1
     
    		AnotherSpecificObject inst4 = new AnotherSpecificObject(); // inst4.champProblematique = 3
    		AnotherSpecificObject inst5 = new AnotherSpecificObject(); // inst5.champProblematique = 3
     
    		YetAnotherSpecificObject inst6 = new YetAnotherSpecificObject(); // levée de l'exception
    	}
    }
    Solution peut-être à peaufiner encore un peu, mais pour l'instant ça me va.

    Un grand à tous les deux !


    Je mets ce sujet en résolu, par contre j'ai encore une petite question... rien de bien important mais je pense que ça rendrait le tout plus élégant.
    Je voudrais bien pouvoir remplacer l'intruction "LinkedObject.Initialize(typeof(SpecificObject), 1);" par "SpecificObject.Initialize(1);"
    Comment faire pour, dans d'une fonction statique, identifier le type de la classe qui l'invoque ? dans le constructeur je peux faire this.GetType(), mais évidemment il n'y a pas de référence à un "this" dans une fonction statique...

  8. #8
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Tu peux essayer ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type taillepeu = MethodInfo.GetCurrentMethod().ReflectedType;
    EDIT : Pas sur que ça ne renvoie pas le type de base... A tester.

  9. #9
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    C'est + - la même chose. Mon implémentation d'une factory ressemblerait à ca:

    Code C# : 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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
     
    public abstract class MDAFactory
        {
     
            public abstract MDA GetMDA();
     
        }
     
     public class SpecificObjectMDAFactory : MDAFactory
        {
            private static MDA myMDA = null;
            public override MDA GetMDA()
            {
                if (myMDA == null)
                {
                    myMDA = new MDA();
                    //traitement specifique
                }
                return myMDA;
            }
        }
     
     
     
        public  class AnotherSpecificObjectMDAFactory : MDAFactory
        {
            private static MDA myMDA = null;
            public override MDA GetMDA()
            {
                if (myMDA == null)
                {
                    myMDA = new MDA();
                    //traitement specifique
                }
     
                return myMDA;
            }
        }
     
        public class SpecificObject : LinkedObject
        {
            public SpecificObject()
                : base(new SpecificObjectMDAFactory())
            {
     
            }
        }
     
        public class AnotherSpecificObject : LinkedObject
        {
            public AnotherSpecificObject()
                : base(new AnotherSpecificObjectMDAFactory())
            {
     
            }
        }
     
        public abstract class LinkedObject
        {
            private MDA champProblematique;
     
            public LinkedObject(MDAFactory factory)
            {
                champProblematique = factory.GetMDA();
            }
        }

    Déjà le gros avantage est qu'on ne se soucit plus d'initialiser l'objet.

    j'ai jeté un coup d'oeil sur le Multition. Il assure bien l'unicité des objets mais mais ne se soucit pas de leurs création. Derniere chose, il faut bien choisir la clé de la collection pour assurer l'unicité, et la je pense que le nom de la classe fera l'affaire.

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Points : 909
    Points
    909
    Par défaut
    @SaumonAgile :
    En effet c'est le type de base qui est renvoyé... donc ça ne marche pas, snirfl

    @mehdi_tn :
    Pour les factories, je verrai... Comme je l'ai dit, il me reste à peaufiner le code, et je n'ai pas encore tout à fait une vision d'ensemble de la façon dont mes classes s'imbriquent.
    (oui je sais c'est pô bien, il faudrait que je me mette sérieusement à la modélisation globale de ma librairie, mais j'ai du mal à me poser et à le faire sans me précipiter sur l'ordi pour vérifier si mes idées "marchent"... et par exemple, dans ce cas, je ne savais pas si ce que je voulais était vraiment possible, donc j'essaie sur des petits bouts de code avant d'assembler tous les morceaux)

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

Discussions similaires

  1. opacité pour la couleur de cellule mais pas pour le contenu
    Par koKoTis dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 05/12/2013, 15h04
  2. Réponses: 3
    Dernier message: 02/03/2010, 08h16
  3. [PDO] Syntaxe pour une classe qui hérite de PDO
    Par fey dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 18/10/2009, 20h58
  4. Réponses: 2
    Dernier message: 29/01/2008, 22h53
  5. Réponses: 7
    Dernier message: 25/03/2005, 14h05

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