没有if,切换实现Factory的最佳方法

goR*_*Gon 3 java design-patterns factory factory-pattern

我正在寻找许多方法来实现Java中的Factory模式,但仍然找不到一个完美的方法,如果/ switch plus不使用反射,则不会受到影响.我找到的最好的一个是Tom Hawtin在这里的答案:https://stackoverflow.com/a/3434505/1390874

但我最担心的是它将匿名类的HashMap存储在内存中.

问题是除了Tom Hawtin的答案之外,人们还会考虑使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Mis*_*sha 8

如果您使用的是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();
Run Code Online (Sandbox Code Playgroud)

你甚至可以拥有enum工具Supplier<Animal>,然后做AnimalFarm.valueOf("Meow").get();.


k_g*_*k_g 0

尝试这样的事情:

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
Run Code Online (Sandbox Code Playgroud)

这根本不使用反射、if、 或, 。switch