4 votes

comment déterminer le type de sous-classe dans un modèle de fabrique autrement qu'en utilisant if else et switch ?

Je voulais essayer le modèle de fabrique et j'ai pu l'implémenter, mais quand
générant pour plus de quelques classes, j'ai pensé que ce sera laid ! donc toute clarté ou suggestion serait vraiment appréciée....

Ma Superclasse :

public abstract class Output {

    public abstract void generate(Data dat); }

J'ai mes autres classes qui s'étendent à partir de Output comme

public class generateXML extends Output{
.
.
.
}

Ma question est liée à ce qui suit :

public class generatorFactory(){

public Output generate(String str){   

// ou obtenir un objet en tant qu'argument comme (Object obj)

if(str.equals("xml"){  
return new generateXML();  
}  
else if.........  
......  
}

Existe-t-il un moyen de déterminer le type de sous-classe en évitant de vérifier chaque type ?

2voto

mariosangiorgio Points 1424

Vous devriez envisager de remplacer votre chaîne if-else par une carte.

Plutôt que d'avoir à écrire le code qui vérifie toutes les chaînes que vous voulez prendre en charge, il suffit d'une copule de lignes pour récupérer l'élément dans la carte.

Vous aurez, bien sûr, besoin d'un peu plus de code de configuration pour placer les éléments dans la carte, mais cela devrait être trivial.

Ici Il s'agit d'un bon article sur ce sujet (en PHP).

1voto

AmitD Points 12541

Vous pouvez utiliser enum qui peut être passé à la fabrique et retourner l'objet de la fabrique basé sur l'enum passé. La seule chose est que vous ne pouvez pas l'exporter comme API.

 enum Type
{
    XML {
        @Override
        public Object getFactory() {
            // TODO Auto-generated method stub
            return null;
        }
    };

    public abstract Object getFactory();
} 

Si vous devez l'exposer comme une API, vous pouvez faire quelque chose comme ci-dessous.

interface IType {
    public abstract Object getTypeFactory();
}

enum Type implements IType {
    XML {
        @Override
        public Object getTypeFactory() {
            // TODO Auto-generated method stub
            return null;
        }
    };
}

Et changer l'implémentation de la méthode Factory en

public static Object getFactoryByType(String name) {
    Type type = Type.valueOf(name);
    return type.getTypeFactory();
}

1voto

Peter Lawrey Points 229686

Vous pouvez utiliser Reflection.

Object generated = getClass().getMethod("generate" + type.toUpperCase()).invoke(this);

public Object generateXML();
public Object generateJSON();
public Object generateCSV();

0voto

Michael Laffargue Points 5190

Puisque vous devez appeler new à chaque fois, je ne suis pas sûr qu'on puisse contourner le processus de branchement. Quelqu'un doit savoir quoi te rendre.

Si c'était pour les singletons, vous pourriez initialiser un HashMap "xml"=>generateXML singleton

Après une seconde réflexion, vous pouvez modifier votre attribut String pour des raisons différentes. Type classes MyTypeXML, MyTypeJSON, ... et ensuite utiliser une méthode avec le même nom mais de type différent.

public Output generate(MyTypeXML xml) { // This will go for XML }
public Output generate(MyTypeJSON json) { // This will go for JSON }

Mais pour les usines, je ne suis pas vraiment contre le codage if...else.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X