2012-11-15 2 views
0

J'ai créé la classe d'usine et je me demande quelle est la meilleure façon de l'implémenter. Option 1Quelle est la meilleure façon de créer la classe d'usine

public class Factory { 

    private IProperty prop; 
    public IDoc doc; 

    public Factory(int version) { 
     switch (version) { 
      case '1': 
       prop = new Prop(); 
       doc = new Docu(); 
     ... 
      case '2': 
      prop = new Prop1(); 
      doc = new Docu1(); 
     ... 
     } 
    } 

    public IProperty getProperty() { 
     return this.prop; 
    } 

    public IDoc getDoc() { 
     return this.doc; 
    } 
} 

Ma question est de savoir si le faire comme-à-dire définir membre avec le type d'interface et pour allumer le constructeur ou pour chaque méthode get à utiliser l'instruction switch plutôt sur le constructeur, donc dans la constructeur, je vais simplement obtenir la version et enregistrez-le sur membre de la classe et que, par exemple, utiliser comme

public IProperty getProperty() { 
switch (version) { 
    case '1': 
    prop = new Prop(); 
    case '2': 
    prop = new Prop1(); 
... 

Alors, quelle est la meilleure façon, ou toute autre idée?

+0

Votre première version ne sera même pas compilée. Votre commutateur est en dehors de toute méthode. Ce n'est pas autorisé. Et selon votre question, la 2e option est toujours une meilleure façon de procéder. Laissez la méthode 'getProperty' décider de la façon dont elle construit la' propriété'. –

+0

Encore une question, pourquoi votre usine a une référence non statique au lieu de références statiques? –

+0

La première ou la deuxième voie est possible - elles ont une différence mineure. Dans le premier cas, les instances 'IProperty' /' IDoc' renvoyées par la même instance de 'Factory' seront toujours les mêmes, alors que dans le second cas il est toujours possible de changer les instances retournées par l'instance' Factory' pendant sa durée de vie. Bien que la présence de l'instruction 'switch' indique clairement que le polymorphisme peut (et devrait effectivement) être utilisé à la place de celui-ci - veuillez vous référer à la réponse' bobah' qui décrit comment cela est fait. – Yura

Répondre

0
  • Tout d'abord, votre Factory devrait idéalement avoir static references au lieu de non-static un. Et il devrait avoir un static method à créer/obtenir l'instance appropriée.

  • Deuxièmement, il est préférable d'avoir deux usines différentes pour différents types .

  • Troisièmement, je nommerais votre méthode comme createProperty, plutôt que getPropertyObject, parce que cette méthode ne retourne pas le déjà créé instance plutôt la création d'un.

Bien sûr, getPropertyObject('1'), semble comme il est la récupération d'une property pour cette version à partir d'un stockage de persistance, qui n'est pas ce qu'il fait. C'est plutôt créer une instance basée sur la version.

(NOTE: - Nom de static factory methods sont importants, ils sont parmi l'un des avantages, ils ont plus constructors Depuis un name, vous pouvez deviner ce qui est exactement ce que factory method fait..)

Cela dit , Je dirais, que le 2nd option serait mieux avec tous ces changements.Laissez la méthode createProperty décider, comment il veut créer le instance.

Alors, je modifierais votre code comme ceci: -

public class PropertyFactory { 
    private static IProperty prop; 

    public static createProperty(char version) { 

     switch (version) { 
      case '1': 
       prop = new Prop(); 
       break; // Don't forget a `break` here. 
      case '2': 
       prop = new Prop1(); 
       break; 

      default: // do have a default case 
       prop = null; 
     } 
     return prop; 
    } 
} 

De même, vous pouvez créer un DocumentFactory pour créer un document object. Nommez la méthode: - createDocument(char version)

0

Votre deuxième moyen est toujours préférable car chaque appelant de vos méthodes get* recevra une nouvelle instance de l'objet. Si vous créez les deux objets dans le constructeur, vous devrez gérer les problèmes de partage d'objets (encore plus si vous utilisez ces objets dans des threads différents).

0

L'idée de créer une usine est beaucoup mieux dans votre première version que dans la seconde.

Idéalement, il ne devrait pas être le constructeur de la classe d'usine mais une méthode statique.

public class Factory 
{ 
    public static IProperty getPropertyObject(char version) 
    { 
     switch (version) 
     { 
      case '1': 
       return new Prop(); 

      case '2' 
       return new Prop1(); 
     } 
    } 

    public static IDoc getDocObject(char version) 
    { 
     switch (version) 
     { 
      case '1': 
       return new Doc(); 

      case '2' 
       return new Doc1(); 
     } 
    } 
} 
+1

Une méthode statique réduirait la testabilité car elle introduirait une référence matérielle sur une classe spécifique. – SpaceTrucker

0

Cela dépend de votre situation.

La première option suggère que votre IProperty et IDoc ont des versions différentes mais pour chaque version de l'une vous avez une version correspondante de l'autre.

Alors que la deuxième option suggère que les versions de ceux-ci pourraient être indépendants les uns des autres.

5

Le moyen le plus propre consiste à exposer ce que vous faites en deux usines distinctes en leur donnant une base abstraite commune ou un argument de politique réutilisable si elles ont quelque chose à partager. Un type d'usine ne devrait créer qu'un type d'objet particulier (disons seulement des outils en plastique). La configuration publique d'usine ne contient normalement que les propriétés nécessaires pour créer des objets (contacts de fournisseurs, brevets) ou des propriétés statiques d'objets créés (type de plastique, disons), mais pas de type/classe d'objets.

En outre, quelque chose qui est un stockage d'objets à vie longue comme dans votre exemple n ° 1 devrait probablement être appelé "contexte", pas "usine".

Exemple de code ci-dessous.

public interface IFactory { 
    IDoc createDoc(); 
    IProp createProp(); 
} 

public class Type1Factory implements IFactory { 
    @Override public IDoc createDoc() { return new Doc1(); } 
    @Override public IProp createProp() { return new Prop1(); } 
} 
+1

Je voulais juste écrire quelque chose de similaire mais j'ai remarqué cette réponse, en ajoutant +1 :) La méthode décrite est en fait appelée "Abstract Factory" pattern que l'on peut facilement google et qui a beaucoup d'avantages sur les autres implémentations. – Yura

+0

+1 pour cette ligne significative ** Un type d'usine ne doit créer qu'un seul type d'objet particulier. ** – exexzian

Questions connexes