我的问题是这个。假设您有一个接口,用于定义如何实现转换器。这个接口可以有一个方法loadDocument()和另一个convert()。现在假设我们想要有多个转换器,ConvertHTML2DOC,ConvertXML2HTML e.t.c你就明白了。
假设您获得了转换为2个字符串所需的两种格式(无论您如何获得它们都无关紧要)。现在,您需要创建转换器的实例并转换文档。
我的问题是哪个更好:实际创建精心设计的if语句或通过Class类反射加载类?为了证明我写了一个我的意思的小例子。在我的例子中,我有两个共享一个接口的P1和P2类。我还创建了50000个以显示速度差异。事实证明,正常的调用稍微快一点,但我认为在一个复杂的例子中,例如我在开头提到的那个,通过Class方法创建类的好处更方便,更易于维护。你有什么想法?
import java.util.*;
public class Test {
public static void main(String[] args) {
try {
Random r = new Random();
Date test1start = new Date();
for (int i = 0; i<= 50000; i++){
Printable p = (Printable)Class.forName("P"+(r.nextInt(2)+1)).newInstance();
System.out.println(p.getString());
}
Date test1stop = new Date();
Date test2start = new Date();
for (int i = 0; i<= 50000; i++){
Printable p;
if (r.nextInt(2) == 0 ) {
p = new P1();
} else {
p = new P2();
}
System.out.println(p.getString());
}
Date test2stop = new Date();
System.out.println("Test with 'Class' invocation took "+(test1stop.getTime()-test1start.getTime())+" milliseconds.");
System.out.println("Test with 'normal' invocation took "+(test2stop.getTime()-test2start.getTime())+" milliseconds.");
} catch (Exception e) {
}
}
}
interface Printable {
public String getString();
}
class P1 implements Printable {
public String getString(){
return "1";
}
}
class P2 implements Printable {
public String getString(){
return "2";
}
}
答案 0 :(得分:6)
你绝对应该遵循Javier的建议 - 工厂注册表是解决这个问题的正确方法。我过去已经多次实现它,用于格式转换或其他一些可扩展的“基于谓词”的工厂解决方案(例如,基于反射信息的自动GUI生成)。
然而,我会建议添加一个设计 - 引入所有翻译人员所针对的通用域模型(CDM)。假设你有格式A,B和C,你需要支持每种格式之间的转换 - 你得到所有的排列:随着格式数量的增加,您将获得大量的转换!更好的想法是将每个转换分成两部分 - 让我们称之为导入程序和导出程序。导入器将格式转换为公共域模型(CDM),而导出将CDM转换为某种格式。
例如,我们将从A到B的转换分解为以下内容:
现在,当您想要添加新格式时,您只需要编写导入程序和导出程序,但您可以从所有其他格式进行翻译!谈论可扩展性!它还允许您可以读取但不能写入的格式,反之亦然。
因此,解决方案是拥有进口商工厂的注册表和出口商工厂的注册表。
答案 1 :(得分:3)
绝对使用工厂方法;但不是“大if
”或名称修改,而是使用“类注册”方法。为此,工厂类维护一个表,其中每个具体类注册它的条件(在您的情况下,它是源和目标名称)和构造函数(它是'condition-&gt;构造函数'字典)。工厂本身只是构造字典键并获取它所需的构造函数。
一个很大的优点是每个具体的类都封装了它所解决的条件,你可以在不改变工厂方法的情况下添加更多。
答案 2 :(得分:-1)
尝试类似这样的事情,使用Class.forName的单行性编译时间安全性。
public class PrintableFactory
{
public enum Type
{
HTML,
DOC,
}
public static Printable getPrintable(final Type from, final Type to)
{
final Printable printable;
if(from == HTML && to == DOC)
{
printable = new HtmlToDoc();
}
else if(from == DOC && to == HTML)
{
printable = new DocToHTML();
}
else
{
// you decide if you want runtime or compile time exception handling
// could also return numm but I don't like that myself.
throw new ImpossibleConversionException(from, to);
}
return (printable);
}
}