2011-04-18 26 views
1

我有一个Forum类与一些子类,并且我将子类名称作为一个字符串字段存储在数据库沿所有其他字段。当我检索该对象时,我希望它成为同一类的实例。我可以做很多if-else语句来查找要调用哪个子类构造函数,但是它不容易扩展。决定在执行时间实例化哪个子类

我发现这个解决方案,但感觉莫名其妙脏:

public static Forum createForum(int forumId, String kind) { 
     try { 
      Class cls = Class.forName("forum."+kind); 
      Constructor ct = cls.getConstructor(Integer.TYPE, String.class); 
      Object retobj = ct.newInstance(forumId, kind); 
      return (Forum) retobj; 
     } 
     catch (Throwable e) { 
      System.err.println(e); 
     } 
     return null; 
    } 

有没有更好的解决办法?

谢谢。

+0

您也可以在这里使用'int.class'而不是'Integer.TYPE'。 – 2011-04-18 22:54:26

回答

1

我可以做很多if-else语句来查找要调用的子类构造函数,但它不容易扩展。

一种替代方法是创建一个“工厂对象”界面为你Forum类,然后填充工厂实例地图创建每个子类的。

public interface ForumFactory { 
    public Forum createForum(String arg); 
} 

public class FooForumFactory implements ForumFactory { 
    public Forum createForum(String arg) { return new FooForum(arg); } 
} 

Map<String, ForumFactory> factories = new HashMap<String, ForumFactory>(); 
factories.put("foo", new FooForumFactory()); 
factories.put("bar", new BarForumFactory()); 

... 

// Create an instance ... 
Forum forum = factories.get(forumType).createForum(forumName); 

如果不同的子类构造函数需要不同的参数,情况会更加困难。但这对您的反射解决方案也会有问题。

从长远来看,使用ORM(如Hibernate)可能会给出更优雅的解决方案。

+0

我喜欢“有一个新答案”的信息......我刚开始写了一个非常相似的答案。 +1。 – 2011-04-18 22:56:22

0

我想你要找的是什么Object Serialization

(该网页是一个小广告重,但它有一些好的信息。谷歌搜索“Java对象序列化”将返回大量的信息)

Oracle教程在这里:http://java.sun.com/developer/technicalArticles/Programming/serialization/

+0

我也想到了这一点,但它不一定适用于SQL数据库,因为它会干扰规范化或可查询性。 (要么复制数据,要么无法查询它。) – 2011-04-18 22:26:23

+0

取决于......他可能只是为了持久。您也可以实现一个序列化,将其存储在数据库中,就像他现在正在做的那样(效率不高但方便)。在此之后,您将进入使用Hibernate等整个ORM的事情,但是了解序列化是很好的。 – 2011-04-18 22:33:07

0

是的,还有一种替代方法 - 对象关系映射(ORM),它可以帮助您 - 还有更多。 Java的ORM框架包括Hibernate和DataNucleus。

+0

谢谢,但我不想重新编码我已拥有的所有持久性管理。不过,我会看看我的下一个项目。 – 2011-04-18 22:47:28