Java 基于前提条件创建新实例的最佳方法
嗨,我的问题是这个。假设您有一个定义如何实现转换器的接口。此接口可以有一个loadDocument()方法和另一个convert()。现在假设我们想要有多个转换器,ConvertHTML2DOC,ConvertXML2HTML e.t.c,你就知道了 假设您在两个字符串中获得了需要转换的两种格式(不管您如何获得它们)。现在您需要创建转换器的实例并转换文档 我的问题是哪一个更好:实际创建一个详细的if语句,还是通过类的反射加载类?为了证明我写了一个小例子来说明我的意思。在我的示例中,有两个类P1和P2共享一个接口。我还创建了50000个,以显示速度差异。事实证明,正常调用的速度稍快一些,但我认为在一个复杂的示例中,如我在开头提到的示例中,通过Class方法创建类的好处更方便,也更易于维护。你的想法是什么Java 基于前提条件创建新实例的最佳方法,java,Java,嗨,我的问题是这个。假设您有一个定义如何实现转换器的接口。此接口可以有一个loadDocument()方法和另一个convert()。现在假设我们想要有多个转换器,ConvertHTML2DOC,ConvertXML2HTML e.t.c,你就知道了 假设您在两个字符串中获得了需要转换的两种格式(不管您如何获得它们)。现在您需要创建转换器的实例并转换文档 我的问题是哪一个更好:实际创建一个详细的if语句,还是通过类的反射加载类?为了证明我写了一个小例子来说明我的意思。在我的示例中,有两个类P1和
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";
}
}
import java.util.*;
公开课考试{
公共静态void main(字符串[]args){
试一试{
随机r=新随机();
日期test1start=新日期();
对于(inti=0;i请尝试这样的方法,编译时安全性,使用一行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);
}
}
当然要使用工厂方法;但是不要使用“bigif
”或名称混乱,而是使用“class registration”方法。为此,工厂类维护一个表,每个具体类在其中注册它的条件(在您的例子中是源和目标名)和构造函数(它是一个“条件->构造函数”字典).工厂本身只是构造字典键并获取它所需的构造函数
一个最大的优点是,每个具体类都封装了它所解决的条件,并且您可以在不更改工厂方法的情况下添加更多的条件。您肯定应该遵循Javier的建议-工厂注册是解决此问题的正确方法。我在过去多次以这种方式实现它,用于格式转换或者其他一些可扩展的基于“谓词”的工厂解决方案(例如,基于反射信息的GUI自动生成)
然而,我建议在设计中增加一项内容,即引入一个通用域模型(CDM),该模型是所有翻译人员的目标。假设您有格式a、B和C,您需要支持每种格式之间的转换,您可以获得所有排列:
- A->B
- A->C
- B->A
- B->C
- C->A
- C->B
随着格式数量的增加,您会得到大量的转换!更好的方法是将每个转换分为两部分——我们称之为导入器和导出器。导入器将格式转换为公共域模型(CDM),而导出器将格式从CDM转换为某种格式
例如,我们将从A到B的转换分解为以下内容:
- A-->CDM(这是一个导入)
- CDM-->B(这是一个导出)
现在,当你想添加一个新的格式时,你只需要编写一个导入器和导出器,但你可以从所有其他格式中得到翻译!谈论可扩展的!它还允许你可以读取但不能写入的格式,反之亦然
因此,解决方案是建立进口商工厂和出口商工厂的注册。好吧……你不喜欢这样做是因为?如果你不说你为什么反对投票,你怎么能期望人们从反对投票中学到一些东西?可能是因为它缺乏OP显然试图实现的可扩展性?