Лучший способ реализовать 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 вообще.