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

Logging Java Discussion :

Implémenter le design pattern Factory


Sujet :

Logging Java

  1. #1
    Nouveau membre du Club
    Inscrit en
    mars 2005
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 46
    Points : 38
    Points
    38
    Par défaut Implémenter le design pattern Factory
    Je suis en train de développer une application qui, à un certain moment donne à l'utilisateur la possibilité d'ajouter un attribut à un enregistrement qu'il crée, cet attribut peut être une chaine de caractère (je programme en Java donc c’est un String) où bien c’est un numérique (Double). J’ai opté pour la création d’une factory qui utilise l’interface Attribut qui est elle, est implémentée par mes mes deux classes concrètes AttributNumérique et AttributTexte. La Factory comprenait un block if pour identifier l’objet à créer.
    Plus tard, le besoin a évolué et j’ai eu besoin de donner la possibilité d’ajouter comme classe concrète un Booléen, trouvant le bloc if assez lourd et ne voulant pas modifier le code à chaque ajout de nouvelle classe j’ai utilisé la reflexion pour trouver la bonne classe. Pour une création manuelle ça a été bien, mais lors d’un import massif depuis le PGI j’ai commencé à remarquer que les lenteurs commençaient à ne plus être négligeables.
    Est-ce que vous connaissez un moyen autre que le bloc if then else et la reflexion pour déterminer la classe concrète à instancier?
    J’ai cherché des façons d’implémentation et dans un site j’ai trouvé 3 méthodes, les deux que j’ai utilisé plus une troisième que je n’arrive pas à comprendre, voici le code utilisé
    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
     
    abstract class Product
    {
    	public abstract Product createProduct();
    	...
    }
     
    class OneProduct extends Product
    {
    	...
    	static
    	{
    		ProductFactory.instance().registerPhoneCall("ID1", new OneProduct());
    	}
    	public OneProduct createProduct()
    	{
    	return new OneProduct();
    	}
    	...
    }
     
    class ProductFactory
    {
    	public void registerPhoneCall(String productID, Product p)    {
    		m_PhoneCallClasses.put(productID, p);
    	}
     
    	public Product createProduct(String productID){
    		((Product)m_RegisteredProducts.get(productID)).createProduct();
    	}
    }
    J’avoue ne pas avoir compris la méthode utilisée, quelqu’un peut m’aider à comprendre ça?

  2. #2
    Expert confirmé

    Homme Profil pro
    SDE
    Inscrit en
    août 2007
    Messages
    2 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : SDE

    Informations forums :
    Inscription : août 2007
    Messages : 2 013
    Points : 4 319
    Points
    4 319
    Par défaut
    Bonjour,

    Est-ce que ces deux implémentation ont vraiment une raison d'être ? J'entends par là : est-ce que la différence entre ces deux classes n'est pas uniquement présente au niveau de l'initialisation de ces dernières (notamment au niveau des paramètres de constructeur). Si c'est le cas peut-être qu'une simple surcharge de constructeur suffirait à se passer d'une factory.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Product {
        public Product(String initParam) {}
        public Product(Double initParam {}
    }
    Si deux implémentations se justifient, alors on peut-être qu'une simple méthod factory suffirait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    abstract class Product {
        public static Product create(Double initParam) { return new DoubleProduct(); }
        public static Product create(String initParam) { return new StringProduct(); }
    }
     
    class DoubleProduct extends Product {}
    class StringProduct extends Product {}
    On peut donc raisonablement se passer d'une Factory, cependant ca reste possible :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    interface Product {}
    class StringProduct implements Product {}
    class DoubleProduct implements Product  {}
    class ProductFactory {
        public static Product create(Double initParam) { return new DoubleProduct(); }
        public static Product create(String initParam) { return new StringProduct(); }
    }
    Dans tous les cas il n'est pas forcément utile d'avoir un if pour gérer ça, l'overloading est bien plus élégant. L'utilisation de Factory est très utile lorsqu'on va avoir plusieurs types de factories mais lorsque l'on veut juste masquer la construction, la plupart du temps une simple méthode factory fait l'affaire et évite la prolifération des classes.
    http://alaindefrance.wordpress.com
    Certifications : SCJP6 - SCWCD5 - SCBCD5 - SCMAD1
    SDE at BitTitan

  3. #3
    Nouveau membre du Club
    Inscrit en
    mars 2005
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 46
    Points : 38
    Points
    38
    Par défaut
    Merci pour ta réponse.

    J'ai pensé à cette solution, d'ailleurs c'est la solution implémenté à l'heure actuelle (la plus simple à mes yeux et surtout facile à maintenir).
    Maintenant, mon challenge (rien à voir avec le client) c'est de trouver un moyen pour ne pas toucher au code de la factory, imagine que demain on demande qu'un paramètre de type date soit demandé, je dois éditer le code de la factory et du test, dans un moins on me demande un booléen et rebelote, sans entrer dans la possibilité d'avoir besoin de passer mes propres objets en paramètre, là ça va devenir ingérable. Le réflexion traite ce problème mais ralentit le traitement.
    Les 3 solutions que j'ai trouvé nécessitent obligatoirement un changement de code et une recompilation, donc, je crois que je vais m'orienter un peu plus vers de l'injection, je pense à Spring IoC, mais comme je ne suis pas expert de ce framework, j'aimerais savoir si un connaisseur peut m'indiquer si Spring peut vraiment faire ce qu'il prétend être.

  4. #4
    Nouveau membre du Club
    Inscrit en
    mars 2005
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 46
    Points : 38
    Points
    38
    Par défaut
    Avec Spring, le problème semble résolu, je ne l'ai pas testé, au fait je ne sais pas si c'est comme ça que ça fonctionne, quelqu'un devrait valider ceci:

    Java code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    interface Product {}
    class StringProduct implements Product {}
    class DoubleProduct implements Product  {}
    class ProductFactory {
    	//paramType est l'id du Bean dans le fichier de configuration
        public static Product create(String paramType) { (Product) (new XmlBeanFactory(new ClassPathResource("MonFichierDInjection.xml"))).getBean(paramType);}
    }
    Mon fichier XML:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <bean id="String" class="StringProduct">
        <!-- Initialisation de la classe et des valeurs -->	
    </bean>
    <bean id="Double" class="DoubleProduct">
        <!-- Initialisation de la classe et des valeurs -->	
    </bean>
    Si j'ai un ajout de classe je crois pouvoir faire ceci:

    Java code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class DateProduct implements Product {}
    Mon fichier XML:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <bean id="Date" class="DateProduct">
        <!-- Initialisation de la classe et des valeurs -->	
    </bean>
    Si on passe le mauvais paramètre à la méthode create on est protégé par l'exception NoSuchBeanDefinitionException.

    J'aimerais bien avoir une validation avant de plonger - réellement - dans la documentation de Spring et développer le truc, peut être que le sujet devrait être déplacé dans le bon forum?

  5. #5
    Nouveau membre du Club
    Inscrit en
    mars 2005
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 46
    Points : 38
    Points
    38
    Par défaut
    ça fonctionne!
    Est-ce que c'est plus rapide que la reflexion? j'ai pas réalisé de benchmark, mais je n'ai pas vraiment l'impression que ça l'est

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

Discussions similaires

  1. design pattern factory
    Par olive_le_malin dans le forum C++
    Réponses: 2
    Dernier message: 23/08/2007, 15h31
  2. Classe + design pattern factory
    Par Rodrigue dans le forum C++
    Réponses: 8
    Dernier message: 07/11/2006, 14h42
  3. [Conception]Design Pattern Factory ?
    Par ®om dans le forum Logging
    Réponses: 8
    Dernier message: 13/09/2006, 10h20
  4. [Fabrique] [Java] Design Pattern Factory
    Par SkyBioSS dans le forum Design Patterns
    Réponses: 3
    Dernier message: 24/05/2006, 14h53

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