我正在尝试构建工厂对象,但是很难找到一种用Java实现它的好方法。
我正在编写的应用程序用于处理各种格式的文件,因此有一个CodecInterface,适用于用于读写文件的所有类。假设它定义了以下方法。这些文件中的每一个都有一个唯一的人工指定的ID字符串,用于对编码器\解码器进行ID识别。
String read(); void write(String data); String getID();
工厂类将具有用于创建这些编解码器类实例的create方法。我想方法签名看起来像这样。
static CodecInterface CodecFactory.create(String filename, String codecid, String args);
文件名是要读取/写入的文件的名称,编解码器是指示要使用哪种编解码器的唯一ID。args参数是传递给正在生成的解码器/编码器对象的参数字符串。它的返回应该是所请求的编解码器对象的实例。
我见过的所有Factory示例通常都在create方法内部包含一个switch语句,该语句根据ID创建对象实例。我想避免这样做,因为这似乎不是“正确”的方法,这也意味着除非您修改create方法,否则列表几乎是固定的。理想情况下,我想使用像字典(由编解码器ID索引)之类的东西,其中包含可用于创建所需的编解码器类实例的东西(我将称之为神秘类ClassReference)。再次使用一些准Java代码,这就是我作为create方法的主体所想的。
static Dictionary<String, ClassReference>; static CodecInterface CodecFactory.create(String filename, String codecid, String args); { ClassReference classreference; classreference = codeclibrary(codecid); return classreference.instanceOf(args); }
ID的字典很简单,但是我不知道应该使用什么ClassReference。类引用应该允许我创建所需类的实例,如上例所示。
从网上看,类方法和instanceOf似乎都朝着正确的方向发展,但是我还没有发现任何可以将两者结合在一起的东西。更为复杂的是,要创建的对象的构造函数将带有参数。
我应该看的任何提示将不胜感激。
提前致谢。
解
感谢大家的建议。最后,我从您的所有建议中总结了一些建议,并提出了以下建议,这些建议似乎很奏效。
请注意,我已经省略了很多“健全性/错误检查”代码以炫耀重要的位。
import java.lang.reflect.Constructor; import java.util.HashMap; public class CodecFactory { private static HashMap<String, Class<? extends CodecInterface>> codecs; static { codecs = new HashMap<String, Class<? extends CodecInterface>>(); //Register built-in codecs here register("codecA", CodecA.class); register("codecB", CodecB.class); register("codecC", CodecC.class); } public static void register(String id, Class<? extends CodecInterface> codec) { Class<? extends CodecInterface> existing; existing = codecs.get(id); if(existing == null) { codecs.put(id, codec); } else { //Duplicate ID error handling } } public static CodecInterface create(String codecid, String filename, String mode, String arguments) { Class<? extends CodecInterface> codecclass; CodecInterface codec; Constructor constructor; codec = null; codecclass = codecs.get(codecid); if(codecclass != null) { try { constructor = codecclass.getDeclaredConstructor(String.class, String.class, String.class, String.class); codec = (CodecInterface)(constructor.newInstance(codecid, filename, mode, arguments)); } catch(Exception e) { //Error handling for constructor/instantiation } } return codec; } }
尝试这样的事情:
public class CodecFactory { final private static Map<String, Class<? extends CodecInterface>> codecLibrary; static { codecLibrary = new HashMap<String, Class<? extends CodecInterface>>(); codecLibrary.put("codec1", Codec1.class); //... } static CodecInterface create(String filename, String codecid, String args) throws InstantiationException, IllegalAccessException { Class<? extends CodecInterface> clazz; clazz = codecLibrary.get(codecid); CodecInterface codec = clazz.newInstance(); codec.setArgs(args); codec.setFilename(filename); return codec; } }