使用Singleton设计模式实现解决方案的建议

时间:2015-11-19 14:57:34

标签: java design-patterns singleton test-framework

我需要实施一个解决方案作为Test framework& amp;的一部分。我正在考虑单身模式,原因如下所述。但是,我无法实现我的预期解决方案。因此需要对可能的实施提出一些建议/意见。

问题陈述: 我有一个环境(我正在测试的产品的环境)配置属性文件,我想加载&使参数的值可以全局访问测试框架。 我想使用单例模式,因为这些属性是一次性值(如果尝试多次初始化则应该报告异常),应该全局可用&有一点访问方法。

然而,属性/参数列表真的很长&因此,将其分解为模块(类)是明智的。对于下面的解释,我试着用作文。

例如

public class Configuration {
    private static Configuration configObj;
    private static Database dbDetails;
    private static Machine macDetails;
    //...
    //... many more modules

    public static synchronized void createInstance(Properities envProps){
          //Should create only one instance of Configuration 
          // and should also initialize Database & Machine objects.
    }

    public static Configuration getConfigObject(){
         return configObj;
    }
}


public class Database {
    private static String dbConnectString;

    public Database(String dbcs){
         dbConnectString = dbcs;
    }

    public static String getDbConnectString(){
         return dbConnectString;
    }
}


public class Machine {
    private static String hostname;
    private static String loginUsername;

    public Machine(String hostname,String loginUsername){
        this.hostname = hostname; //It may include some trimming/cleaning
        this.loginUsername = loginUsername;
    }

    public static String getHostName(){
        return hostname;
    }
}

PS:只是一个示例输入代码,用于理解我的问题陈述。

期望:现在的期望是,在尝试获取主机名时,我应该通过Configuration静态对象获得单一访问点(假设我已成功初始化了所有成员变量),即

String hostname = Configuration.getHostname();

OR

String hostname = Configuration.getConfigObject()。getHostname();

当前问题: 如何使用组合或继承创建一个引用所有方法的静态对象(从概念上讲,组合将是正确的方法)。

多重继承可以解决这个问题,但Java并不支持如此排除。不能考虑接口,因为覆盖所有方法是繁琐的和冗长的参数/方法将随着时间的推移而不断变化。

即使需要废弃此设计模式,也欢迎所有建议。尝试不同的东西。

1 个答案:

答案 0 :(得分:0)

您将无法自动"委托静态调用模块。即使调用不是静态的,如你所说,Java也不支持多重继承。

选项1:

让您的主Configuration类提供将实例返回到模块的静态方法。每当您想要读取配置条目时,首先获取模块实例,然后查询条目本身:

Configuration.getDatabaseConfiguration().getServerName();

此方法的优点是很清楚您所指的配置的哪一部分。如果您只使用Configuration.getServerName(),则无法确定是否要检索数据库的服务器名称或网络服务器。

选项2:

如果您能够使用Java 8并且您的配置很大,但非常简单(在编译时静态知道或可从极少数实例中提取),您可以考虑使用新的默认接口方法(https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/

然后,您将为每个模块创建一个接口,其中所有getter都具有默认实现。您的主配置类将实现所有模块接口,而不会覆盖任何方法。这样,可以从一个对象查询所有配置条目,但您仍然必须通过静态方法获取此对象。这与您可以获得的多重继承一样接近。我肯定会推荐选项1。