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

Algorithmes et structures de données Discussion :

[Conception] héritage et overriding


Sujet :

Algorithmes et structures de données

  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2007
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 254
    Par défaut [Conception] héritage et overriding
    Bonjour,

    J'ai une question de conception. C'est un peu long à expliquer. J'espère que ça ne vous fera pas fuir. J'ai essayé d'être le plus clair possible.

    J'ai 3 classes :
    Un interface ISellable,
    une classe abstraite Product qui étends cet interface ISellable
    et une classe Drug qui hérite de Product

    L'interface définit 3 méthodes : update, save and delete. J'aimerais que chacune de ces action soient logués dans un fichier ou une table, peut importe. J'ai donc une méthode static Audit.log() qui me permet de loguer un message. J'ai moi même développé les classes ISellable et Product mais je permet à d'autres développeurs de créer autant de classes héritant de Product qu'ils en ont besoin. Mes classes ISellable et Product font partie d'une même librairie dont je suis le seul à pouvoir modifier le code.

    La classe Drug par contre peut être écrite par n'importe qui. De même qu'une classe Food par exemple pourrait aussi hériter de Product. Toutes ces classes Drug, Food, etc... ont leur propre manière de réaliser leurs Update, Save et Delete. Le problème c'est que si le développeur oublie de commencer ou finir sa méthode spécifique par un base.Update(), base.Save() ou base.Delete() mon appel à Audit.Log ne sera jamais réalisé. Je ne peux pas me le permettre.

    En d'autres mots j'aimerais que chacune des actions des produits qui hérite de la classe Product soie logué sans que le développeur n'ai à intervenir ou à se soucier de cela. En fait il n'en a même pas le droit. Le log doit se passer même si le développeur oublie de le préciser dans son overriding. De même qu'il ne peut pas loguer un autre message que celui prévu dans le classe Product.

    Dans mon code ci-dessous ca ne vas pas marcher. Si je crée un objet de type Drug et que j'utilise sa méthode Save() il ne va faire que le DoSomething() et ne va pas aller voir le code de la méthode Save de Product.

    Il est clair qu'il y a une erreur dans ma conception. Voyez vous ce que je fait de mal et comment je peux y remédier ?

    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
     
    namespace SellableLib
    {
    	public interface ISellable
    	{
    		void Delete(string sales);
    		void Save(string sales);
    		void Update(string sales, bool exists);
    	}
     
    	abstract class Product : ISellable
    	{
    		#region ISellable Members
     
    		public void Delete(string sales)
    		{
    			Audit.Log("Deleted");
    		}
     
    		public void Save(string sales)
    		{
    			Audit.Log("Saved");
    		}
     
    		public void Update(string sales, bool exists)
    		{
    			Audit.Log("Updated");
    		}
     
    		#endregion
    	}
    }

    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
     
    using SellableLib;
    namespace MedicalApp
    {
    	internal class Drug : Product
    	{
    		public void Delete(string sales)
    		{
    			DoSomething();
    		}
     
    		public void Save(string sales)
    		{
    			DoSomething();
    		}
     
    		public void Update(string sales, bool exists)
    		{
    			DoSomething();
    		}
    	}
    }

    Mon code est en C# mais la solution peut être dans un autre langage. J'ai ajouté un zip avec le projet en VS 2005.

    Merci,
    Fichiers attachés Fichiers attachés

  2. #2
    ndp
    ndp est déconnecté
    Membre expérimenté Avatar de ndp
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 227
    Par défaut
    Salut,

    je pense que ton idee est d'inverser le controle entre la classe Product et une ConcreteProduct. Hollywood principle -> ne nous appelez pas, nous vous rappelerons.

    Il faut que ca soit ta classe Product qui ait le control sur le traitement, comme ca les classes filles n'ont pas a s'en soucier.
    Concretement, ca peut se faire de plusieur facons, tu pourrais par exemple voir a utiliser le pattern Template Method.

  3. #3
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Les solutions que je vois sont:

    - L'inversion de contrôle (moteur de persistance)
    - La programmation orientée aspect (avec un pointcut sur tes méthodes)
    - L'utilisation d'une classe abstraite a la place d'une interface (ça rejoint un peu l'inversion de contrôle, mais en "local" dans la classe)


    Je rejoins la proposition de ndp: l'inversion de contrôle me parait le plus simple.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  4. #4
    Membre éclairé
    Inscrit en
    Septembre 2007
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 254
    Par défaut
    Je ne connais pas très bien les 3 solutions que tu proposes.

    - Qu'est ce que l'inversion de contrôle ?
    - Je connais l'idéologie de la programmation orientée aspect mais ou puis je trouver plus d'info concrète ? Qu'est ce que ces pointcuts ?
    - L'utilisation d'une classe abstraite à la place d'une interface... C'est le design pattern template ça ?

    Je ne demande pas une tartine d'explication mais pourrais tu me diriger vers de la documentation sur ces différents sujet. Surtout sur l'inversion de contrôle. Merci bien.

    Dran

  5. #5
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Citation Envoyé par DranDane Voir le message
    - Qu'est ce que l'inversion de contrôle ?
    Cela consiste a concentrer une responsabilité (souvent technique) dans une seule classe dédiée. Dans ton cas, tu aurais une classe dédiée pour la persistance, "PersistEngine", avec les methodes update(), delete() et save(). Ces methodes prennent en parametre une instance d'une interface "IPersistable" que doivent implémenter tes produits. Quand tu as besoin de sauver un produit, au lieu de faire "product.save()" tu fais "persistengine.save(product)".

    Code java : 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
     
    interface IPersistable {
    	int getId();
    	int getType();
    	byte[] getData();
    }
     
    class PersistEngine {
    	public void delete(IPersistable object) { /*...*/ }
    	public void save(IPersistable object) { /*...*/ }
    	public void update(IPersistable object) { /*...*/ }
    }
     
    class Drug implements IPersistable {
    	private int id;
     
    	public byte[] getData() { /* ... */ }
    	public int getId() { return this.id; }
    	public int getType() { return Type.Drug; }
     
    }

    - Je connais l'idéologie de la programmation orientée aspect mais ou puis je trouver plus d'info concrète ? Qu'est ce que ces pointcuts ?
    Les pointcuts sont les endroits ou tu veux que le code du greffon soit inséré. Dans ton cas, le greffon contiendrait le code du Log, et il serait inséré juste avant/après les appels a save(), update() et delete()

    - L'utilisation d'une classe abstraite à la place d'une interface... C'est le design pattern template ça ?
    Oui, c'est ca.

    Code java : 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
     
    abstract class Product {
    	public void delete() { /*...*/ onDelete(); /*...*/ }
    	public void save()   { /*...*/ onSave();   /*...*/ }
    	public void update() { /*...*/ onUpdate(); /*...*/ }
     
    	abstract protected void onUpdate();
    	abstract protected void onSave();
    	abstract protected void onDelete();
    }
     
    class Drug extends Product {
    	protected void onDelete() { /* ... */ }
    	protected void onSave()   { /* ... */ }
    	protected void onUpdate() { /* ... */ }
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  6. #6
    Membre éclairé
    Inscrit en
    Septembre 2007
    Messages
    254
    Détails du profil
    Informations forums :
    Inscription : Septembre 2007
    Messages : 254
    Par défaut
    Merci Pseudocode pour tes solutions et explications. Merci aussi à ndp. A moi de choisir la meilleur solution en fonction de mon architecture actuelle.

    Sujet résolu.

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

Discussions similaires

  1. héritage et override methodes sous .NET
    Par julien.63 dans le forum ASP.NET
    Réponses: 15
    Dernier message: 15/10/2008, 16h47
  2. Conception : héritage et instanceof
    Par herve91 dans le forum Langage
    Réponses: 10
    Dernier message: 05/12/2006, 18h11
  3. Conception: héritage d'une classe abstraite
    Par Kikito dans le forum Langage
    Réponses: 19
    Dernier message: 05/10/2006, 18h36
  4. [conception] Héritage comment faire ?
    Par bohor2gannes dans le forum Modélisation
    Réponses: 11
    Dernier message: 15/02/2006, 18h35
  5. [heritage][conception]héritage multiple en java!
    Par soulhouf dans le forum Langage
    Réponses: 9
    Dernier message: 25/08/2005, 21h03

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