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

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

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

问题是除了Tom Hawtin的回答之外,人们还会考虑使用Class.newInstance()吗? 这样可以避免我们在内存中存储不必要的匿名类吗? 加上代码会更干净。

它看起来像这样:

class MyFactory { private static final Map factoryMap = Collections.unmodifiableMap(new HashMap() {{ put("Meow", Cat.class); put("Woof", Dog.class); }}); public Animal createAnimal(String action) { return (Animal) factoryMap.get(action).newInstance(); } } 

如果您使用的是java 8,则可以设置如下的enum

 enum AnimalFarm { Meow(Cat::new), Woof(Dog::new); public final Supplier factory; private AnimalFarm(Supplier factory) { this.factory = requireNonNull(factory); } } ...... Animal dog = AnimalFarm.valueOf("Woof").factory.get(); 

您甚至可以使用enum实现Supplier然后执行AnimalFarm.valueOf("Meow").get();

尝试这样的事情:

 class MyFactory { private static final Map> factoryMap = Collections.unmodifiableMap(new HashMap() { put("Meow", Cat.BASE_INSTANCE); put("Woof", Dog.BASE_INSTANCE); }); public Animal createAnimal(String action) { return factoryMap.get(action).instance(); } } interface Animal { public SELF instance(); } class Cat implements Animal { public static final Cat BASE_INSTANCE = new Cat(); public Cat() {} public Cat instance(){ return new Cat(); } } // And a similar Dog class 

这根本不使用reflection, if或者switch

Java 8引入了一些不错的lambda和function接口,这使得这非常简单。 它还避免了您在以前的Java版本中必须编写的许多丑陋的样板代码。 有一件事并不是很清楚,那就是如何使用带有多个参数的构造函数来处理创建对象。 大多数Java的function接口允许一个参数或根本不允许任何参数。 在这种情况下,解决方案是实现您自己的function接口。

想象一下,你的Animal类都有如下所示的构造函数:

 public Dog(String name, int age) { // constructor stuff } 

您可以在工厂类中创建一个名为Factory的函数接口,该接口具有3个参数。 前两个参数是您要传递给构造函数的对象类型,第三个参数将是您要返回的对象。

 public class AnimalFactory { private static final Map> factoryMap; static { Map> realMap = new HashMap<>(); factoryMap = Collections.unmodifiableMap(realMap); realMap.put("MEOW", Cat::new); realMap.put("WOOF", Dog::new); } public static Animal createAnimal(String action) { return factoryMap.get(action).create(node); } @FunctionalInterface private interface Factory { S create(T obj1, R obj2); } } 

如果所有类都使用no-arg构造函数,那么您可以删除自定义接口并使用类似于Supplier东西。 但其他一切应该或多或少保持不变。