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

Design Patterns Discussion :

[Java] La "Factory" Késako ? [Fabrique]


Sujet :

Design Patterns

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut [Java] La "Factory" Késako ?
    Bonjour,
    quelqu'un pourrait t'il m'expliquer , en vulgarisant et/ou en me donnant un exemple si possible du Pattern Factory ...... qui dit on est tres souvent utilisé

    Mais je ne vois pas du tout a quoi il sert et en quoi il simplifit les choses !!!

    Merci par avance de vos réponses.

    B.

  2. #2
    Membre éprouvé
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Points : 1 085
    Points
    1 085
    Par défaut
    Le pattern Factory est une usine pour créer des objets suivant un paramètre ou suivant des conditions, imagines que tu ai une interface FactoryResult et plusieurs implémentations FactoryResultImpl1 et FactoryResultImpl2 ... FactoryResultImplN

    Alors une factory pourrait être:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    plublic class Factory {
       public static FactoryResult getInstance(int valeur) {
          if (valeur == 1) {
             return new FactoryResultImpl1();
          } else if (valeur == 2) {
             return new FactoryResultImpl2();
          } ...
          else if (valeur == N) {
             return new FactoryResultImplN();
          }
       }
    }
    http://www.patterndepot.com/put/8/factory.pdf

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut
    Ok, en fait c'est tres simple alors !!!!

    Par exemple je veux me connecter a une base de donnée mais les méthodes different ( connectionMySQL ou connectionDB2 )je peux donc utiliser ce pattern.

    --> factory.getInstance("DB2") qui me renvérrait un connectionDB2.

    Mais bon il faut connaitre a l'avance le cas et donc l'objet à récupérer car il y à un passage de parametre. Mais bon je peux mettre ce parametre dans un fichier de config !!!!!

  4. #4
    Membre éprouvé
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Points : 1 085
    Points
    1 085
    Par défaut
    Yesssssssss !!!!!!!!!!!

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut
    Thanks you !!!!

  6. #6
    Membre éprouvé
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Points : 1 085
    Points
    1 085
    Par défaut
    Petite précision tu aurais par exemple un interface Connector avec une méthode abstraite connect();

    et tu peux alors avoir deux classes

    ConnectorDB2 et ConnectorMySql qui implémentent Connector

    et

    Factory.getInstance("DB2") te renvoie un objet de type Connector qui est une instance de ConnectorDB2...

    Ct juste une précision...

    A+

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut
    Merci de la précision, et justement je me posais la question sur cette notion d'heritage !!!

  8. #8
    Membre habitué
    Inscrit en
    Octobre 2002
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 164
    Points : 190
    Points
    190
    Par défaut
    Petite précision sur la philosophie générale :

    Sans utiliser de passage de paramètre dans la méthode de fabrique, l'instanciation d'une classe dans la méthode d'une classe est à proscrire.

    Pourquoi ?

    Parce que le changement potentiel de l'implémentation à utiliser aura un impact à de nombreux endroits dans le code avec des risques de régression évidentes.
    Ainsi en utilisant une fabrique qui renvoi une interface tu caches l'implémentation réellement utilisée. Toutes les méthodes de ton application qui ont besoin d'une instance utiliser la fabrique pour récupérer cette dernière. Ainsi si demain tu changes d'implémentation il te suffit de modifier ta méthode de fabrication et l'ensemble de ton code est à jour. De plus l'utilisation d'une interface limite les risques de regression en découplant le besoin du client avec l'implémentation réelle.

    Bien sûr tout ceci est un beau discours auquel il faut apporter des bémols. Tu ne va pas utiliser des fabriques partout dans ton application. Le truc consiste à repérer les éventuels changements pouvant intervenir dans ton programme et c'est à ces endroits que tu mettras ce type de pattern. Ou comme le dit XP, tu attends que ces modifications arrivent pour mettre en place de tels mécanismes ce qui est une méthode plus pragmatique.

    Puisque tu t'intéresses à ce pattern renseigne toi sur les autres pattern de base qui simplifie la vie des programmeurs

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut
    Merci jIdJo pour ta longue réponse,

    mais je ne suis vraiment pas fort quand il s'agit de comprendre un texte technique !!! Autrement dis je suis assez novice en POO et un bon exemple de code me parle beaucoups plus ............ Et c'est d'ailleur pour ca que j'ai du mal a comprendre les patterns !!!

    Est ce que tu pourrais m'expliquer par le code cette petite phrase :

    Sans utiliser de passage de paramètre dans la méthode de fabrique, l'instanciation d'une classe dans la méthode d'une classe est à proscrire.
    Merci par avance

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut
    ou quelqu'un d'autre

  11. #11
    Membre habitué
    Inscrit en
    Octobre 2002
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Octobre 2002
    Messages : 164
    Points : 190
    Points
    190
    Par défaut
    Je me suis relu et mon texte n'était pas très clair

    Exemple "mauvais" :
    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
    public class A {
    }
    
    public class B {
      public void method1 {
        A a = new A();
        ...
        ...
      }
    }
    
    public class C {
      public void method2 {
        ...
        A a = new A();
        ...
        ...
      }
    }
    Si tu veux modifier le comportement de A, tu as la solution de faire de l'héritage cad :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public class AA extend A {
    ...
    }
    et de surcharger certaines méthodes. AA étendant A, les classes B et C n'y verront que du feu. Cependant l'héritage n'est pas toujours à conseillé et personnellement je l'évite autant que possible.

    Donc la deuxième technique est de créer une autre classe A2. Du coup le problème est que tu dois modifier ton code dans la classe B et C pour avoir ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class B {
      public void method1 {
        A2 a = new A2();
        ...
      }
    }
    
    idem pour la classe C
    Et là tu dois avoir fait attention à ce que A et A2 est les mêmes méthodes et rien ne l'oblige dans la structure des classes. Donc pour améliorer le code il faut passer par 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
    public interface AIntf {
      public void doSomething();
    }
    
    public class A implements AIntf {
      ...
    } 
    
    public class A2 implements AIntf {
    }
    
    public class B {
      public voic method1 {
        AIntf a = new A();
        ...
      }
    }
    
    idem pour la classe C
    Quand tu veux utiliser la classe A2 il suffit alors de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class B {
      public void method1() {
        AIntf a = new A2();
        ...
      }
    }
    
    idem pour la classe C
    Cela limite les changements mais ne les réduit pas à néant.
    Et enfin la solution avec la factory :

    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
    public class B {
      public void method1() {
        Aintf a = AFactory.create();
        ...
      }
    }
    
    public class C {
      public void method1() {
        ....
        Aintf a = AFactory.create();
        ...
      }
    }
    
    public class AFactory {
      public static AIntf create() {
        return new A();
      }
    }
    Demain tu veux utiliser A2 il te suffit de changer la ligne dans la factory et retourner un new A2(). Il n'y a aucun changement de code dans les classes B et C.

    Dans l'absolue il ne faudrai jamais utiliser de classe concrète mais toujours des interfaces et donc créer les instances concrétes remplissant le contrat des interfaces à travers des Factory.

    Cela remplit un principe essentiel :
    OCP (Open Closed Principle)
    Principe d'ouverture fermeture : Le code doit être ouvert aux changements (dans le sens comportement) mais fermé aux modifications de code. En gros on ne doit pas modifier le code pour changer le comportement.

    Ce principe permet de réduire considérablement les risques de régression d'une application lors d'une modification.

    Voilà j'espère ne pas t'avoir trop embrouillé surtout si tu débutes.
    Bonne chance.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut
    Merci jidjo je vais lire ca ce soir a tete reposé et je te tiens au courant ....... en tout cas merci de ta disponibilité.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 147
    Points : 64
    Points
    64
    Par défaut
    Merci beaucoups jIdJo,

    J'ai bien compris ce que tu voulais expliquer et les exemples m'ont bien aidé.

    Donc la "théorie" voudrait que chaque classe implémente une interface.

    Je vais étudier les differents pattern de programmation, je peux déja ajouter celui la mes connaissances personnelles

    Merci à vous deux de votre patience et votre disponibilité.

    Je vous dis à plus tard en ce moment je ne suis pas avard de question

  14. #14
    Membre habitué

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 28
    Points : 139
    Points
    139
    Par défaut
    La solution à la mode pour ce problème très général c'est l'Inversion de contrôle alias l'injection de dépendances (IoC) qui permet, allié à la programmation sur des interfaces plutôt que des objets, comme expliqué par jIdJo, de rendre les différentes parties d'une appli réellement indépendantes, facilitant les tests et permettant d'affranchir les classes métier de l'utilisation de toute API propriétaire. Ce type d'approche est facilité par l'utilisation d'un conteneur léger type Spring

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

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