使用单例设计模式实施解决方案的建议
Suggestions for implementing a solution using Singleton design pattern
我需要实施一个解决方案作为测试框架的一部分,我正在考虑单例模式,原因如下所述。但是,我无法实现我预期的解决方案,因此需要一些 suggestions/inputs 可能的实现。
问题陈述:
我有一个环境(我正在测试的产品的环境)配置属性文件,我想加载它并使测试框架可以全局访问参数的值。
我想使用单例模式,因为这些属性是一次性值(如果尝试多次初始化应该报告异常),应该全局可用并且可以一次性访问这些方法。
但是,properties/parameters 的列表确实很长,因此将其分成模块 (类) 是明智的。对于下面的解释,我尝试了组合。
例如
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 静态对象进行单点访问(假设我已经初始化了所有成员变量成功)即
字符串主机名 = Configuration.getHostname();
或
字符串主机名 = Configuration.getConfigObject().getHostname();
当前问题:
如何使用组合或继承创建一个引用所有方法的静态对象(从概念上讲,组合是正确的方法)。
多重继承本来可以解决这个问题,但是Java不支持所以排除了。也不能考虑接口,因为重写所有方法既乏味又冗长,而且 parameters/methods 会随着时间不断变化。
欢迎所有建议,即使它需要放弃这种设计模式并尝试不同的东西。
您将无法"automatically" 将静态调用委托给模块。即使调用不是静态的,如您所说,Java 也不支持多重继承。
选项 1:
让您的主要 Configuration
class 提供静态方法 return 实例到您的模块。每当你想读取配置条目时,首先获取模块实例,然后查询条目本身:
Configuration.getDatabaseConfiguration().getServerName();
这种方式的好处是很清楚你指的是你配置的哪一部分。如果您只使用 Configuration.getServerName()
,则无法区分是要检索数据库的服务器名称还是网络服务器的名称。
选项 2:
如果您能够使用 Java8 并且您的配置很大,但非常简单(在编译时静态已知或可从极少数实例中提取),您可以考虑使用新的默认接口方法( https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/).
然后您将为每个模块创建一个接口,其中所有 getter 都有默认实现。您的主要配置 class 将在不覆盖任何方法的情况下实现所有模块接口。这样所有的配置项都可以从一个对象中查询出来,但是你还是得通过静态方法来获取这个对象。这与您所能得到的最接近多重继承。不过,我肯定会推荐选项 1。
我需要实施一个解决方案作为测试框架的一部分,我正在考虑单例模式,原因如下所述。但是,我无法实现我预期的解决方案,因此需要一些 suggestions/inputs 可能的实现。
问题陈述: 我有一个环境(我正在测试的产品的环境)配置属性文件,我想加载它并使测试框架可以全局访问参数的值。 我想使用单例模式,因为这些属性是一次性值(如果尝试多次初始化应该报告异常),应该全局可用并且可以一次性访问这些方法。
但是,properties/parameters 的列表确实很长,因此将其分成模块 (类) 是明智的。对于下面的解释,我尝试了组合。
例如
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 静态对象进行单点访问(假设我已经初始化了所有成员变量成功)即
字符串主机名 = Configuration.getHostname();
或
字符串主机名 = Configuration.getConfigObject().getHostname();
当前问题: 如何使用组合或继承创建一个引用所有方法的静态对象(从概念上讲,组合是正确的方法)。
多重继承本来可以解决这个问题,但是Java不支持所以排除了。也不能考虑接口,因为重写所有方法既乏味又冗长,而且 parameters/methods 会随着时间不断变化。
欢迎所有建议,即使它需要放弃这种设计模式并尝试不同的东西。
您将无法"automatically" 将静态调用委托给模块。即使调用不是静态的,如您所说,Java 也不支持多重继承。
选项 1:
让您的主要 Configuration
class 提供静态方法 return 实例到您的模块。每当你想读取配置条目时,首先获取模块实例,然后查询条目本身:
Configuration.getDatabaseConfiguration().getServerName();
这种方式的好处是很清楚你指的是你配置的哪一部分。如果您只使用 Configuration.getServerName()
,则无法区分是要检索数据库的服务器名称还是网络服务器的名称。
选项 2:
如果您能够使用 Java8 并且您的配置很大,但非常简单(在编译时静态已知或可从极少数实例中提取),您可以考虑使用新的默认接口方法( https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/).
然后您将为每个模块创建一个接口,其中所有 getter 都有默认实现。您的主要配置 class 将在不覆盖任何方法的情况下实现所有模块接口。这样所有的配置项都可以从一个对象中查询出来,但是你还是得通过静态方法来获取这个对象。这与您所能得到的最接近多重继承。不过,我肯定会推荐选项 1。