Utilisez les scannotations !
Étape 1. Créez une annotation comme ci-dessous :
package animal;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface AniMake {
String action();
}
Notez que le RetentionPolicy est exécutable, nous y accéderons par réflexion.
Étape 2. (Facultatif) Créez une super classe commune :
package animal;
public abstract class Animal {
public abstract String greet();
}
Étape 3. créer les sous-classes avec votre nouvelle annotation :
package animal;
@AniMake(action="Meow")
public class Cat extends Animal {
@Override
public String greet() {
return "=^meow^=";
}
}
////////////////////////////////////////////
package animal;
@AniMake(action="Woof")
public class Dog extends Animal {
@Override
public String greet() {
return "*WOOF!*";
}
}
Étape 4. Créez l'usine :
package animal;
import java.util.Set;
import org.reflections.Reflections;
public class AnimalFactory {
public Animal createAnimal(String action) throws InstantiationException, IllegalAccessException {
Animal animal = null;
Reflections reflections = new Reflections("animal");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(AniMake.class);
for (Class<?> clazz : annotated) {
AniMake annoMake = clazz.getAnnotation(AniMake.class);
if (action.equals(annoMake.action())) {
animal = (Animal) clazz.newInstance();
}
}
return animal;
}
/**
* @param args
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
AnimalFactory factory = new AnimalFactory();
Animal dog = factory.createAnimal("Woof");
System.out.println(dog.greet());
Animal cat = factory.createAnimal("Meow");
System.out.println(cat.greet());
}
}
Cette usine peut être nettoyée un peu, par exemple en gérant les méchantes exceptions vérifiées, etc.
Dans cette usine, j'ai utilisé le Réflexions bibliothèque.
J'ai fait cela à la dure, c'est-à-dire que je n'ai pas fait de projet maven et j'ai dû ajouter les dépendances manuellement.
Les dépendances sont :
Si vous avez sauté l'étape 2, vous devrez modifier la méthode factory pour qu'elle renvoie Object.
A partir de là, vous pouvez continuer à ajouter des sous-classes, et tant que vous les annotez avec AniMake (ou tout autre nom plus approprié que vous trouverez), que vous les placez dans le paquetage défini dans le constructeur de Reflections (dans ce cas "animal"), et que vous laissez le constructeur no-args par défaut visible, alors la fabrique instanciera vos classes pour vous sans avoir à être modifiée elle-même.
Voici le résultat :
log4j:WARN No appenders could be found for logger (org.reflections.Reflections).
log4j:WARN Please initialize the log4j system properly.
*WOOF!*
=^meow^=