intérêt du pattern factory

intérêt du pattern factory - Divers - Programmation

Marsh Posté le 26-03-2006 à 11:12:39    

quel est l'intérêt d'utiliser le pattern Factory , plutôt que d'utiliser le concept d'interface et de classe dérivée , je capte pas.
 
exemple :
Interface: Vehicule
Classe dérivée : Voiture , Scooter
 
dans le main :
Vehicule vf = new Voiture()
Vehicule vs = new Scooter()
 
avec le pattern factory:
 
FabriqueAbstraite
FabriqueConrèteVoiture : return new Vehicule()
FabriqueConcrèteScooter: return new Scooter()
 
dans le main:
FabriqueAbstraite fv = new FabriqueConrèteVoiture()
FabriqueAbstraite fs = new FabriqueConcrèteScooter()
Vehicule vv = fv.fabrique()
Vehicule vs = fs.fabrique()
 
 
je vois pas le gain , et l'intérêt d'utiliser ce pattern , need help

Reply

Marsh Posté le 26-03-2006 à 11:12:39   

Reply

Marsh Posté le 26-03-2006 à 12:04:29    

le Factory te permet de déporter le choix de la classe concrète à instancier dans un unique objet.
l'intéret, c'est que si tu as plusieurs clients qui te demandent les caractéristiques d'une voiture, tu n'es pas obligé de réécrire le code d'instanciation de la classe à chaque fois. tu demandes au factory de te construire l'objet qui va bien, et ça roule. ça évite aussi de répercuter toutes les modifs dans tous les clients (imagine que tu veuilles rajouter un véhicule de type "Vélo" : tu devras, pour chaque classe, rajouter le code de création du vélo, alors que dans le Factory, tout est centralisé et tu ne le fais qu'une fois)


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 12:41:06    

Pourtant dans le client il y a bien cette ligne de code :

Code :
  1. FabriqueAbstraite fv = new FabriqueConrèteVoiture()


Si je souhaite que ce même client utilise désormais des vélos, je serais bien obliger de changer la ligne d'instanciation de la fabrique concrète (passer de FabriqueConrèteVoiture() à FabriqueConcrèteVélo() )
tout comme je l'aurais fait en changeant new Voiture en  new Velo()
 
L'intérêt et là je comprendrais c'est que cette ligne

Code :
  1. FabriqueAbstraite fv = new FabriqueConrèteVoiture()

ne soit pas dans le code du client.
Mais si elle n'est pas dans le client où se situe t-elle dans le code ? c'est peut être ça que je vois pas...

Reply

Marsh Posté le 26-03-2006 à 14:21:29    

ta classe FabriqueAbstraite n'a aucune utilité à mon sens. moi je ferais comme ceci :

Code :
  1. // on créé une interface Vehicle, commune à tous les véhicules
  2. public interface Vehicle
  3. {
  4.   void turnLeft();
  5.   void turnRight();
  6. }
  7.  
  8. // on créé une classe FactoryVehicle, qui construira les types de véhicules souhaités
  9. public class FactoryVehicle
  10. {
  11.   public Vehicle createVehicle(String type)
  12.   {
  13.      if (type.equals("velo" ))
  14.         return new Velo(); // la classe Velo implemente l'interface Vehicle
  15.      else if (type.equals("camion" ))
  16.         return new Camion(); // idem
  17.   }
  18. }
  19.  
  20. // et maintenant le code du client
  21. public static void main (final String[] args)
  22. {
  23.   Vehicle v;
  24.   VehicleFactory f = new VehicleFactory();
  25.   v = f.createVehicle("velo" );
  26.   v.turnLeft();
  27.   v.turnRight();
  28. }


comme ça, si tu as plusieurs clients qui demandent la création d'un véhicule, tu n'as pas besoin à chaque fois de faire un test sur le type de classe concrète à instancier. tu appelles le factory, qui te renverra l'objet construit.
ça facilite également la maintenance : imagine qu'un jour tu veuilles rajouter une classe Train(), le fait de passer par le Factory t'évite de mettre à jour tous les clients. tu ne mets à jour que le Factory


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 14:40:39    

si elle a un intérêt vu qu'un pattern conçu comme ça existe :
sur le web y a une présentation de ce pattern à cette adresse  http://www.dofactory.com/Patterns/PatternFactory.aspx
Et justement je n'arrive pas à saisir l'intérêt de cette fabrique abstraite.

Reply

Marsh Posté le 26-03-2006 à 14:47:45    

Sachant qu'il y a deux patterns avec à peu près la même philosophie,  le abstract factory et le factory. Moi je parle juste du Factory.

Reply

Marsh Posté le 26-03-2006 à 14:55:32    

l'intéret de cette fabrique abstraite, est de permettre à toutes ses sous classes de surcharger la méthode FactoryMethod(), et ainsi d'implémenter leur propre comportement


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 15:10:09    

oui mais dans ce cas, une classe de base et des classes filles spécialisées qui implémente leur propre comportement suffirait.  
je comprends bien l'idée où l'on veut séparer la création de l'utilisation. Mais je comprends pas ce que ça apporte de plus dans le code. Aussi bien au niveau clarté du code , qu'au niveau evolutivité.

Reply

Marsh Posté le 26-03-2006 à 15:12:18    

weblook$$ a écrit :

oui mais dans ce cas, une classe de base et des classes filles spécialisées qui implémente leur propre comportement suffirait.  


ben c'est ce qui se passe dans ton lien non ? [:petrus dei]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 15:23:46    

non.
Tu as d'un côté classe de base (ou interface) et ses classes filles et de l'autre fabrique de base et ses fabrique conrètes dérivées.  

Reply

Marsh Posté le 26-03-2006 à 15:23:46   

Reply

Marsh Posté le 26-03-2006 à 15:29:07    

tu as d'un coté une liste de produits, et de l'autre coté un Factory. les produits partagent des caractéristiques communes, donc ils dérivent tous d'une même interface.
quand au Factory, sa classe de base abstraite permet de créer des sous classes qui permettront de créer des nouveaux produits.
tu auras ainsi un Factory qui crééra un vélo, un autre Factory qui crééra une voiture, etc... mais ces objets seront tous créés avec le même appel, défini dans la classe de base.


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 15:35:24    

weblook$$ a écrit :

Sachant qu'il y a deux patterns avec à peu près la même philosophie,  le abstract factory et le factory. Moi je parle juste du Factory.


Hum non, il y a l'Abstract Factory et le Factory Method, il n'y a pas de "Factory Pattern".
 
Et ici ce dont tu nous parle c'est le pattern Factory Method, l'exemple d'Harko est une SimpleFactory (qui ne fait pas partie des Patterns, et tout cas pas ceux du GoF, c'est plutôt un idiôme)
 
Comme l'a expliqué harko, le principe du Factory Method pattern c'est de définir une interface de création d'objets unique (habituellement via une classe abstraite partiellement implémentée), mais de laisser aux classes dérivées le choix des classes à instancer.
 
Ici l'intérêt est nul (autant utiliser une SimpleFactory) parce que tu n'effectues que la création de l'objet, le Factory Method devient intéressant quand tu as d'autres opérations "standard" à effectuer autour de ton instanciation.
 
Par exemple imaginons qu'après la fabrication d'un véhicule il doive passer un contrôle qualité et une inspection jesaispasquoi.
 
 
On va commencer par prendre deux véhicules

Code :
  1. public abstract class Vehicle {
  2.    // trucs
  3. }
  4.  
  5. public class Car extends Vehicle {
  6.    // implémentation de la voiture
  7. }
  8.  
  9. public class Truck extends Vehicle {
  10.    // implémentation du camion
  11. }


 
Maintenant on crée une VehicleFactory abstraite qui met en place un certain nombre d'opérations standard

Code :
  1. public abstract class VehicleFactory {
  2.    // Ici est la magie du FactoryMethod: elle n'implémente pas la construction de l'objet mais force ses classes dérivées à le faire
  3.    protected abstract Vehicle buildVehicle();
  4.  
  5.    // Par contre elle peut standardiser un certain nombre d'opérations à effectuer
  6.    public Vehicle createVehicle {
  7.        Vehicle machine = buildVehicle();
  8.        doQualityTest(machine); // là normalement on devrait aussi gérer des erreurs si besoin
  9.        doInspection(machine); // ou alors on peut ajouter des pièces, genre les vitres ou les plastiques dans ce cas précis
  10.        return machine;
  11.    }
  12.    protected bool doQualityTest(Vehicle v) {
  13.        // test de qualité
  14.    }
  15.    protected bool doInspection(Vehicle v) {
  16.        // Inspection machin
  17.    }
  18. }


Puis on crée les classes concrètes servant à fabriquer nos véhicules

Code :
  1. public class CarFactory extends VehicleFactory {
  2.    protected Vehicle buildVehicle() {
  3.        return new Car();
  4.    }
  5. }
  6.  
  7. public class TruckFactory extends VehicleFactory {
  8.    protected Vehicle buildVehicle() {
  9.        return new Truck();
  10.    }
  11. }


 
Et au final on utilise le tout

Code :
  1. VehicleFactory carfactory = new CarFactory();
  2. VehicleFactory truckfactory = new TruckFactory();
  3.  
  4. Vehicle vehicule = carfactory.createVehicle();
  5. // on a construit une voiture
  6. Vehicle vehicule = truckfactory.createVehicle();
  7. // on a construit un camion


Dans le Factory Method pattern, la classe au sommet est le Créateur Abstrait, il définit (habituellement) une unique factory method abstraite que les créateurs concrets devront implémenter afin de générer des objets, puis effectue un certain nombre d'opérations sur le produit abstrait (implémenté par les produits concrets générés par les créateurs concrets), mais ce créateur abstrait ne travaille jamais sur des objets concrets (il effectue des opérations génériques).
 
On se retrouve avec deux hiérarchies parallèles (créateur abstrait + créateurs concrets et produit abstrait + produits concrets, les classes abstraites mettent en place toutes les opérations génériques et les classes concrètes définissent l'implémentation réelle), mais si aucune opération n'est effectuée sur les produits (qui puisse être abstraite) le Factory Method pattern devient un gros tas de boilerplate sans intérêt par rapport à une SimpleFactory.
 
Après, l'AbstractFactory c'est encore le niveau d'au dessus (d'ailleurs il est souvent implémenté à coup de FactoryMethod), ça permet de générer des familles complètes d'objets relié ou dépendants entre eux, là encore sans que la Factory initiale (abstraite) ait connaissance des détails gores de l'implémentation.
 
 
C'est plus clair ou je t'ai complètement embrouillé et tu me maudis? [:moule_bite]


Message édité par masklinn le 26-03-2006 à 15:37:03

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 26-03-2006 à 15:38:28    

Sauf que l'objet appelant cette méthode commune sera changeant d'un produit à l'autre: fabriqueconcreteA, fabriqueconcreteB. Et le code permettant de créer l'objet doit se situer dans le client. on sera donc obligé de changer au moins une ligne de code au nvieau du  client si on  change de produit. Tout comme ça aurait été le cas sans fabrique. je comprends pas et je crois que je vais laisser tomber.

Reply

Marsh Posté le 26-03-2006 à 15:44:16    

tu achètes le Head First Design Patterns chez O'Reilly, et tu regardes l'exemple avec la pizzeria, tu verras que ce sera bien plus clair :o


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 15:44:27    

"... mais si aucune opération n'est effectuée sur les produits (qui puisse être abstraite) le Factory Method pattern devient un gros tas de boilerplate sans intérêt par rapport à une SimpleFactory ..."
 
là je dis ouf , j'ai enfin compris , un grand merci , superbe explication

Reply

Marsh Posté le 26-03-2006 à 15:45:51    

weblook$$ a écrit :

"... mais si aucune opération n'est effectuée sur les produits (qui puisse être abstraite) le Factory Method pattern devient un gros tas de boilerplate sans intérêt par rapport à une SimpleFactory ..."
 
là je dis ouf , j'ai enfin compris , un grand merci , superbe explication


ben c'est ce que je t'avais dit depuis le début : la classe FabriqueAbstraite n'a aucune utilité dans l'exemple que tu décris [:petrus75]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 15:47:08    

Harkonnen a écrit :

tu achètes le Head First Design Patterns chez O'Reilly, et tu regardes l'exemple avec la pizzeria, tu verras que ce sera bien plus clair :o


Là je peux pas dire mieux, mon explication étant une adaptation directe de leur PizzaStore :whistle:

Harkonnen a écrit :

ben c'est ce que je t'avais dit depuis le début : la classe FabriqueAbstraite n'a aucune utilité dans l'exemple que tu décris [:petrus75]


Ouais mais tu sais pas expliquer :o


Message édité par masklinn le 26-03-2006 à 15:47:36

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 26-03-2006 à 15:52:47    

oui, mais tu ne m'as pas dit dans quel cas ça pouvait avoir un intérêt. c'est ce qui me manquait pour comprendre.


Message édité par weblook$$ le 26-03-2006 à 15:56:06
Reply

Marsh Posté le 26-03-2006 à 16:03:15    

[:sisicaivrai]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 18:10:31    

Si je résume la chose, ce pattern met en pratique un concept de conception : le masquage d'information. Ici le pattern masque et centralise les détails de création.

Reply

Marsh Posté le 26-03-2006 à 18:15:48    

slash33 a écrit :

Si je résume la chose, ce pattern met en pratique un concept de conception : le masquage d'information. Ici le pattern masque et centralise les détails de création.


Non, il met en pratique le principe selon lequel on doit dépendre d'abstractions (classes abstraites ou interfaces), pas d'implémentations (classes concrètes). Ca n'a strictement rien à voire avec du masquage d'informations.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 26-03-2006 à 18:28:32    

Comme dit dans le Head First : "Designs should be open for extension, but closed for modifications"


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 26-03-2006 à 18:30:23    

Harkonnen a écrit :

Comme dit dans le Head First : "Designs should be open for extension, but closed for modifications"


Aussi, mais ça je le vois plus comme une limitation de java (et donc comme un conseil spécifique à la JOO) qu'autre chose


Message édité par masklinn le 26-03-2006 à 18:31:06

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed