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

avec Java Discussion :

Comment implémenter un comportement commun à plusieurs classes ?


Sujet :

avec Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Septembre 2017
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2017
    Messages : 13
    Points : 7
    Points
    7
    Par défaut Comment implémenter un comportement commun à plusieurs classes ?
    Bonjour,

    J'ai un ensemble de 50 classes environ, et je voudrais toutes leur définir un comportement commun, c'est à dire 2 méthodes : mettons getX et getY dont l'implémentation soit toujours la même pour les 50 classes :
    mais :
    - Je ne veux évidemment pas écrire 50 fois le même code.
    - Je ne peux pas hériter d'une classe abstraite implémentant getX et getY car mes classes héritent déjà d'autres classes.
    - Si je les fais juste implémenter une interface il me faudra tout de même écrire 50 fois le même code.

    j'ai bien entendu parcouru le forum et entendu parler du pattern decorator, mais je n'ai pas l'impression que ça corresponde à mon problème. Si c'est le cas tout de même, pouvez vous m'expliquer comment ?

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    1. Tu peux utiliser une "default method" d'une interface. Cela t'oblige simplement à implémenter l'interface sur toutes les classes. cela peut avoir plus ou moins d'inconvénients (et selon les versions de Java), comme l'impossibilité d'empêcher la redéfinition, ou l'utilisation de variables membres et leur visibilité.
    2. même si toutes tes classes héritent de différentes classes, tu peux toujours faire que la classe la plus générale autre qu'Object soit abstraite et implémentent les méthodes, sauf si certaines de ces classes font partie d'API dont tu ne peux pas modifier les classes
    3. pour limiter la duplication de code, l'utilisation d'une classe de support, avec un attribut interne peut être une solution (cela oblige à implémenter les méthodes pour renvoyer vers les méthodes de classe de support). c'est une technique qu'on met en application par exemple avec java.beans.PropertyChangeSupport.
    4. en terme de pattern, le décorateur pourrait être une solution, ou le visiteur, selon les cas.
      Par exemple, si tu as des classes qui représentent des meubles et que tu veux pouvoir gérer une interface graphique qui permet de placer ces meubles sur un plan, avec des coordonnées, avoir un décorateur qui gère en attribut une position et un meuble est bien plus souple que d'imposer aux meubles d'avoir une position qui n'a pas de sens dans la description d'un meuble (autre que si on a besoin de le positionner) : en plus, on peut utiliser des instances de classe dont ne peut modifier le code.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Septembre 2017
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2017
    Messages : 13
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Salut,

    1. Tu peux utiliser une "default method" d'une interface. Cela t'oblige simplement à implémenter l'interface sur toutes les classes. cela peut avoir plus ou moins d'inconvénients (et selon les versions de Java), comme l'impossibilité d'empêcher la redéfinition, ou l'utilisation de variables membres et leur visibilité.
    2. même si toutes tes classes héritent de différentes classes, tu peux toujours faire que la classe la plus générale autre qu'Object soit abstraite et implémentent les méthodes, sauf si certaines de ces classes font partie d'API dont tu ne peux pas modifier les classes
    3. pour limiter la duplication de code, l'utilisation d'une classe de support, avec un attribut interne peut être une solution (cela oblige à implémenter les méthodes pour renvoyer vers les méthodes de classe de support). c'est une technique qu'on met en application par exemple avec java.beans.PropertyChangeSupport.
    4. en terme de pattern, le décorateur pourrait être une solution, ou le visiteur, selon les cas.
      Par exemple, si tu as des classes qui représentent des meubles et que tu veux pouvoir gérer une interface graphique qui permet de placer ces meubles sur un plan, avec des coordonnées, avoir un décorateur qui gère en attribut une position et un meuble est bien plus souple que d'imposer aux meubles d'avoir une position qui n'a pas de sens dans la description d'un meuble (autre que si on a besoin de le positionner) : en plus, on peut utiliser des instances de classe dont ne peut modifier le code.
    La default method me semble la plus appropriée, mais effectivement je ne peux pas accéder aux variables membres de mes classes ce qui va peut être poser problème.
    Je ne peux pas utiliser la 2e solution pour la raison exacte que tu as cité.
    Je ne comprends pas bien la 3e solution, tu pourras m'expliquer de que tu entends par classe de support ?
    Je ne suis toujours pas convaincu par le decorateur du coup j'explique mon cas.

    Mes 50 classes doivent toutes pouvoir avoir un identifiant unique sous forme de chaine de caractère auquel on peut accéder.
    La méthode qui permet d'y accèder doit avant de le fabriquer, tester s'il est nul et sinon faire appel a une factory qui le crée.
    C'est cette méthode dont je ne veux pas copier 50 fois le code

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    1. Avec la classe de support, au lieu d'avoir ta méthode dans chaque classe, elle se trouve dans une seule classe (support), et chaque classe dispose d'une instance de support à laquelle elle délègue le traitement.
      Au lieu de :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      public class Classe1 {
       
          public String method() {
                /* x lignes de code */
          }
       
      }
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      public class Classe2 {
       
          public String method() {
                /* x lignes de codes (les mêmes que dans Classe2 */
          }
       
      }
      On aura :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      public class Classe1 {
       
          private final Support support = new Support();
       
          public String method() {
               return support.method();
          }
       
      }
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      public class Classe2 {
       
          private final Support support = new Support();
       
          public String method() {
               return support.method();
          }
       
      }
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
       
      public class Support {
          public String method() {
                /* x lignes de code */
          }
      }
    2. Si tu maîtrises le processus d'instanciation (c'est toujours ton code qui décide quand instancier), tu peux faire une fabrique qui produit tes objets en leur associant au besoin un id.
      Si tu ne maîtrises pas le processus d'instanciation, tu peux utiliser juste un décorateur qui va encapsuler les instances de tes objets dans un objet qui contiendra l'id. Ton application ne manipule plus directement les objets mais des objets qui encapsule l'objet et son id.
    3. s'il n'y a pas de processus de persistance et que la notion d'identifiant est associé à la notion d'instance d'objet (donc pas de possibilité d'avoir deux instances d'objets différentes avec le même identifiant en mémoire, pas de copie avec id, en clair), tu peux aussi simplement gérer tes ids avec une map.
      Par exemple :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      public class ObjectIds {
       
      	private static final AtomicInteger INSTANCE_ID_FACTORY = new AtomicInteger();
      	private static final Map<Object, Integer> IDS = new ConcurrentHashMap<>();
       
      	public static Integer getID(Object object) {
      		return IDS.computeIfAbsent(object, obj-> INSTANCE_ID_FACTORY.getAndIncrement());
      	}
       
      }
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      public interface Identified {
       
      	default public int getID() {
      		return ObjectIds.getID(this);
      	}
       
      }
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      public class MyObject1 implements Identified {
       
      	public MyObject1() {
      	}
       
      }
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
       
      		MyObject1 obj1 = new MyObject1();
      		System.out.println(obj1 + " " + obj1.getID());
      		MyObject1 obj2 = new MyObject1();
      		System.out.println(obj2+ " " + obj2.getID());
      		System.out.println(obj1 + " " + obj1.getID());
      		System.out.println(obj2+ " " + obj2.getID());
      idftl.MyObject1@71be98f5 0
      idftl.MyObject1@4411d970 1
      idftl.MyObject1@71be98f5 0
      idftl.MyObject1@4411d970 1


    Tu n'es même pas obligé d'avoir une interface, tu peux aller chercher ton identifiant directement par la méthode ObjectIds.getId(Object), sans méthode sur la classe elle-même, ou sans décorateur (l'intérêt de décorateur, c'est surtout quand la décoration (l'implémentation) n'est pas forcément la même pour tous les objets). Le défault de la méthode par map, c'est la place mémoire que prend la map, et, dans une moindre mesure la recherche dans la map, s'il y a des millions d'instance. Le décorateur empêche ça, avec un impact beaucoup plus léger sur l'occupation mémoire, et un léger impact sur les traitements (on manipule pas directement les instances, mais des adapteurs en fait).

    Citation Envoyé par Flint91300 Voir le message
    La méthode qui permet d'y accèder doit avant de le fabriquer, tester s'il est nul et sinon faire appel a une factory qui le crée.
    Pourquoi doit-il temporairement null ? C'est plus safe qu'un identifiant soit affecté dès que l'instance est à disposition du programme, ça évite d'avoir un workflow état instable sans id puis état stable avec...
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. Méthode commune à plusieurs classes
    Par rvzip64 dans le forum Langage
    Réponses: 15
    Dernier message: 08/12/2008, 14h42
  2. [VS2005] comment organiser une solution avec plusieurs classes
    Par mahboub dans le forum Visual Studio
    Réponses: 1
    Dernier message: 15/04/2008, 10h49
  3. Comment avoir un DataTable commun à plusieurs Forms ?
    Par FANDOR dans le forum Windows Forms
    Réponses: 5
    Dernier message: 27/03/2008, 11h49
  4. Réponses: 8
    Dernier message: 08/03/2006, 16h12
  5. Réponses: 5
    Dernier message: 20/09/2005, 22h48

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