Лучший способ реализовать Factory без if, switch
Я просматривал множество подходов к реализации шаблона Factory в Java и до сих пор не смог найти идеальный, который не страдает от того, что if/switch plus не использует отражение.
Одно из лучших, что я нашел, было в ответе Тома Хотина: qaru.site/info/8552/...
Но моя самая большая проблема заключается в том, что он хранит HashMap анонимных классов в памяти.
Вопрос в том, что люди думают об использовании Class.newInstance() в дополнение к ответу Тома Хотина?
Это позволит избежать хранения ненужных анонимных классов в памяти? Плюс код будет более чистым.
Он будет выглядеть примерно так:
class MyFactory {
private static final Map<String,Class> factoryMap =
Collections.unmodifiableMap(new HashMap<String,Class>() {{
put("Meow", Cat.class);
put("Woof", Dog.class);
}});
public Animal createAnimal(String action) {
return (Animal) factoryMap.get(action).newInstance();
}
}
Ответы
Ответ 1
Если вы используете java 8, вы можете настроить enum
следующим образом:
enum AnimalFarm {
Meow(Cat::new),
Woof(Dog::new);
public final Supplier<Animal> factory;
private AnimalFarm(Supplier<Animal> factory) {
this.factory = requireNonNull(factory);
}
}
......
Animal dog = AnimalFarm.valueOf("Woof").factory.get();
У вас может даже быть enum
реализация Supplier<Animal>
, а затем сделать AnimalFarm.valueOf("Meow").get();
.
Ответ 2
Попробуйте что-то вроде этого:
class MyFactory {
private static final Map<String,Animal<?>> factoryMap =
Collections.unmodifiableMap(new HashMap<String,Class>() {
put("Meow", Cat.BASE_INSTANCE);
put("Woof", Dog.BASE_INSTANCE);
});
public Animal createAnimal(String action) {
return factoryMap.get(action).instance();
}
}
interface Animal<SELF> {
public SELF instance();
}
class Cat implements Animal<Cat> {
public static final Cat BASE_INSTANCE = new Cat();
public Cat() {}
public Cat instance(){
return new Cat();
}
}
// And a similar Dog class
Это не использует отражение, if
или switch
вообще.