2013-04-22 57 views
1

我有一个快速的Java问题。哦,我相当新的Java和计算器,所以请体谅:)如何根据java中的属性文件调用单例类的实例?

让我试着解释我的问题好一点。所以我必须遵循一个单例模式,说两个类A类和B类:

public class A 
{ 
    private static final A INSTANCE = new A() 

    public static A getInstance() 
    { 
     return A.INSTANCE; 
    } 
} 

public class B 
{ 
    private static final B INSTANCE = new B() 

    public static B getInstance() 
    { 
     return B.INSTANCE; 
    } 
} 

现在,我访问这些类的实例从另一个类,假设C:

public class testClassC 
{ 
    A class_instance = A.getInstance(); 
    //or 
    //B class_instance = B.getInstance(); 
} 

什么我想实现的是这个(语法可能是完全错误的,在这一点上,我一直在尝试不同的事情,他们没有工作对我来说):如下

有一个属性文件:

className=A 

然后以某种方式读取从属性文件中的类名,这样,当我改变A到B,我testClassC会让我B.

的实例,我怎样才能做到这一点?哦,再次testClassC是一个测试类,我有一大堆的JUnit测试类,那么最好的方法是什么?

谢谢

+0

你想要它有多灵活?如果你不太在乎它的灵活性,你可以创建一个Map 来存储该类的名字以及该类的单例。 – 2013-04-22 22:28:00

+0

@RobWatts我在哪里存储该Map对象?基本上我有三种类型的存储类:RAM,XML和SQL。然后我有测试我的存储的测试课程。我想要做的是有一个属性文件,我可以将我的类名更改为RAM,然后我的测试类将创建一个RAM存储类实例,并对其进行测试。 – Bahrom 2013-04-22 22:31:54

+0

你应该阅读依赖注入,因为这正是你正在寻找的。这是一篇关于Spring DI的文章(http://www.vogella.com/articles/SpringDependencyInjection/article.html)。你应该仔细阅读它,特别是第6章。 – maba 2013-04-22 23:21:18

回答

2

以下是使用抽象工厂模式的示例。

你有一个interface定义你的类 - 你需要这个,以便你可以抽象出实际的实现。

然后你有一个工厂界面,它定义了newInstance方法。这使得交换工厂模式的单例模式变得非常容易。它还可以轻松地轻松更改工厂实现进行测试。

interface MyInterface { 
} 

interface MyInterfaceFactory { 

    MyInterface newInstance(); 
} 

class MyInterfaceFactoryFromProperties implements MyInterfaceFactory { 

    final Class<? extends MyInterface> myInterfaceImpl; 

    { 
     final Properties properties = new Properties(); 
     try { 
      properties.load(MyInterfaceFactoryFromProperties.class.getResourceAsStream("className.properties")); 
     } catch (IOException ex) { 
      throw new ExceptionInInitializerError(ex); 
     } 
     final String className = properties.getProperty("class.name"); 
     try { 
      myInterfaceImpl = (Class<? extends MyInterface>) MyInterfaceFactoryFromProperties.class.forName(className); 
     } catch (ClassNotFoundException ex) { 
      throw new ExceptionInInitializerError(ex); 
     } 
    } 

    @Override 
    public MyInterface newInstance() { 
     try { 
      return myInterfaceImpl.newInstance(); 
     } catch (InstantiationException ex) { 
      throw new RuntimeException(ex); 
     } catch (IllegalAccessException ex) { 
      throw new RuntimeException(ex); 
     } 
    } 
} 

所以你的工厂实现将遵循这种模式,但你可以,例如,缓存值使其成为一个单例。

该方法从类路径加载属性文件 - 显然这可以更改为文件系统位置。

+0

非常感谢! – Bahrom 2013-04-23 01:10:47

+0

感谢所有其他的响应者,是的,我会阅读依赖注入。我们在速成班中简要介绍了它,但从未真正强调过。我想我会很快发现它的作用。 – Bahrom 2013-04-23 01:12:51