在基础 class.Looking 中使用静态 "member" 变量以获得更好的 approach.Singleton?还是工厂?
Using Static "member" variables in a base class.Looking for a better approach.Singleton? or a Factory?
这可能是一个重复的问题,我尝试寻找答案,但仍无法获得任何帮助。所以,这是场景:
我们有测试套件,有几个测试 classes 和一些其他 classes,我们正在使用它们来设置测试数据。我们有一个基础 class,它的所有 "member" 变量都声明为静态的。 class 中有一个初始设置方法,它加载一个包含所有配置文件数据的地图。然后此映射稍后用于 "initialize" 静态 "class" 变量。
那么这个class就是"extended"作别的用途了。我知道这时候你们都会生气,但说真的,我试着和这里的人交谈,他们只是笑,我很无助。
接下来的故事是: "base" class 不仅提供对一些静态方法的访问,而且还提供对这些静态变量的访问(如上所述)。此外,还编写了一个测试,其中静态变量始终首先被初始化。换句话说,所有这些 classes 都写在 groovy 中。在 groovy 中有一个方法 setUpspec()
到 运行 总是第一个类似于 TestNg
中的 BeforeSuite
,而 setUpspec
是存在的方法在 "base" class 中进行静态变量的所有设置。
我正在提供 class 的快照。我在考虑 Singleton
模式,但也阅读了抽象工厂,我知道这些设计模式,除了无法调用它。
我真的很感激这方面的任何帮助。
这是快照:
class UatBaseClass extends Specification {
public static void setFieldsForTestingPurposes() {
Properties readTestProperties;
try {
readTestProperties = UrlFactory.getEcnConfig("test");
for (String key : readTestProperties.stringPropertyNames()) {
String value = readTestProperties.getProperty(key);
FINAL_CONFIG_MAP.put(key, String.valueOf(value));
}
env = FINAL_CONFIG_MAP.get("v3Env")
mspEnv = FINAL_CONFIG_MAP.get("mspEnv");
isBuildLatestFromBamboo = FINAL_CONFIG_MAP.get("getLatestBuildFromBambooYesOrNo");
isApigeeUsed = FINAL_CONFIG_MAP.get("isApigeeYesOrNo");
clientID = FINAL_CONFIG_MAP.get("client.id");
clientSecret = FINAL_CONFIG_MAP.get("client.secret");
fbIosClientId = FINAL_CONFIG_MAP.get("fb_ios_client_id");
fbIosClientSecret = FINAL_CONFIG_MAP.get("fb_ios_client_secret");
fbAndroidClientId = FINAL_CONFIG_MAP.get("fb_android_client_id");
fbAndroidClientSecret = FINAL_CONFIG_MAP.get("fb_android_client_secret");
runningIosClientId = FINAL_CONFIG_MAP.get("running_ios_client_id");
runningIosClientSecret = FINAL_CONFIG_MAP.get("running_ios_client_secret");
runningAndroidClientId = FINAL_CONFIG_MAP.get("running_android_client_id");
runningAndroidClientSecret = FINAL_CONFIG_MAP.get("running_android_client_secret");
port = FINAL_CONFIG_MAP.get("port");
protocol = FINAL_CONFIG_MAP.get("protocol");
url = new UrlFactory(env);
createUserBaseUrl = url.getCreateUserUrl();
cloudServer = FINAL_CONFIG_MAP.get("server.path")
createUserFinalHost = protocol + "://"+cloudServer;
//added for CoreLeaderboards
coreCommandLeaderBoardUrl = FINAL_CONFIG_MAP.get("DEFAULT_CORE_COMMAND_BASEURL");
coreQueryLeaderBoardUrl = FINAL_CONFIG_MAP.get("DEFAULT_CORE_QUERY_BASEURL");
if(FINAL_CONFIG_MAP.containsKey("challenges_url")) {
challengeElbUrl = FINAL_CONFIG_MAP.get("challenges_url")
}else {
challengeElbUrl = cloudServer
}
} catch (NullPointerException e) {
logger.error("Exception occurred while loading environment values from Jenkins,caught! exception=",e);
}
}
public static String fetchRandomUserIdForTest() {
String randomUpmId = null;
if (isApigeeUsed.equalsIgnoreCase("no")) {
randomUpmId = generateRandomIds();
}
return randomUpmId;
}
public static String generateRandomIds() {
Random rand = new Random();
int userId = rand.nextInt(9000000) + 1000000;
return Integer.toString(userId);
}
public static String getCurrentTimeInMillis() {
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
logger.info("Current time:" + timeStamp);
return timeStamp.toString();
}
private static final Logger logger = LoggerFactory.getLogger(UatBaseClass.class);
public static Map<String,String> FINAL_CONFIG_MAP = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
protected static String clientID;
protected static String clientSecret;
protected static String cloudServer;
protected static String fbIosClientId;
protected static String fbIosClientSecret;
protected static String fbAndroidClientId;
protected static String fbAndroidClientSecret;
protected static String runningIosClientId;
protected static String runningIosClientSecret;
protected static String runningAndroidClientId;
protected static String runningAndroidClientSecret;
protected static String createUserBaseUrl;
protected static UrlFactory url;
protected static String env;
protected static String isApigeeUsed;
protected static String isBuildLatestFromBamboo;
protected static String mspEnv;
protected static String port;
protected static String protocol;
protected static String createUserFinalHost;
protected static String coreCommandLeaderBoardUrl;
protected static String coreQueryLeaderBoardUrl;
protected static String friendsLeaderboardsRouterUrl;
protected static CreateUserDeserializedObject primaryTestUser;
protected static String primaryUserAccessToken;
protected static String challengeElbUrl;
}
所以如果你的问题是多次调用初始化方法,我会选择单例模式。易于实施,不需要您像工厂那样改变工作方式。第一次调用会花费更长的时间进行初始化,接下来的调用只会注意到它已经完成了。正如您所说,我假设您已经熟悉这些模式并知道如何实现它们。
编辑:看到您发布的新代码后,我真的不认为所有这些变量都需要使用额外的内存,尤其是因为它们都是字符串并且您已经将它们全部放在地图中。只需将它们保留在地图上并使用枚举作为可能的键。一个访问函数就足够了。然后,如果您真的想直接访问,请添加从地图中获取的自定义访问方法。
这可能是一个重复的问题,我尝试寻找答案,但仍无法获得任何帮助。所以,这是场景:
我们有测试套件,有几个测试 classes 和一些其他 classes,我们正在使用它们来设置测试数据。我们有一个基础 class,它的所有 "member" 变量都声明为静态的。 class 中有一个初始设置方法,它加载一个包含所有配置文件数据的地图。然后此映射稍后用于 "initialize" 静态 "class" 变量。
那么这个class就是"extended"作别的用途了。我知道这时候你们都会生气,但说真的,我试着和这里的人交谈,他们只是笑,我很无助。
接下来的故事是: "base" class 不仅提供对一些静态方法的访问,而且还提供对这些静态变量的访问(如上所述)。此外,还编写了一个测试,其中静态变量始终首先被初始化。换句话说,所有这些 classes 都写在 groovy 中。在 groovy 中有一个方法 setUpspec()
到 运行 总是第一个类似于 TestNg
中的 BeforeSuite
,而 setUpspec
是存在的方法在 "base" class 中进行静态变量的所有设置。
我正在提供 class 的快照。我在考虑 Singleton
模式,但也阅读了抽象工厂,我知道这些设计模式,除了无法调用它。
我真的很感激这方面的任何帮助。
这是快照:
class UatBaseClass extends Specification {
public static void setFieldsForTestingPurposes() {
Properties readTestProperties;
try {
readTestProperties = UrlFactory.getEcnConfig("test");
for (String key : readTestProperties.stringPropertyNames()) {
String value = readTestProperties.getProperty(key);
FINAL_CONFIG_MAP.put(key, String.valueOf(value));
}
env = FINAL_CONFIG_MAP.get("v3Env")
mspEnv = FINAL_CONFIG_MAP.get("mspEnv");
isBuildLatestFromBamboo = FINAL_CONFIG_MAP.get("getLatestBuildFromBambooYesOrNo");
isApigeeUsed = FINAL_CONFIG_MAP.get("isApigeeYesOrNo");
clientID = FINAL_CONFIG_MAP.get("client.id");
clientSecret = FINAL_CONFIG_MAP.get("client.secret");
fbIosClientId = FINAL_CONFIG_MAP.get("fb_ios_client_id");
fbIosClientSecret = FINAL_CONFIG_MAP.get("fb_ios_client_secret");
fbAndroidClientId = FINAL_CONFIG_MAP.get("fb_android_client_id");
fbAndroidClientSecret = FINAL_CONFIG_MAP.get("fb_android_client_secret");
runningIosClientId = FINAL_CONFIG_MAP.get("running_ios_client_id");
runningIosClientSecret = FINAL_CONFIG_MAP.get("running_ios_client_secret");
runningAndroidClientId = FINAL_CONFIG_MAP.get("running_android_client_id");
runningAndroidClientSecret = FINAL_CONFIG_MAP.get("running_android_client_secret");
port = FINAL_CONFIG_MAP.get("port");
protocol = FINAL_CONFIG_MAP.get("protocol");
url = new UrlFactory(env);
createUserBaseUrl = url.getCreateUserUrl();
cloudServer = FINAL_CONFIG_MAP.get("server.path")
createUserFinalHost = protocol + "://"+cloudServer;
//added for CoreLeaderboards
coreCommandLeaderBoardUrl = FINAL_CONFIG_MAP.get("DEFAULT_CORE_COMMAND_BASEURL");
coreQueryLeaderBoardUrl = FINAL_CONFIG_MAP.get("DEFAULT_CORE_QUERY_BASEURL");
if(FINAL_CONFIG_MAP.containsKey("challenges_url")) {
challengeElbUrl = FINAL_CONFIG_MAP.get("challenges_url")
}else {
challengeElbUrl = cloudServer
}
} catch (NullPointerException e) {
logger.error("Exception occurred while loading environment values from Jenkins,caught! exception=",e);
}
}
public static String fetchRandomUserIdForTest() {
String randomUpmId = null;
if (isApigeeUsed.equalsIgnoreCase("no")) {
randomUpmId = generateRandomIds();
}
return randomUpmId;
}
public static String generateRandomIds() {
Random rand = new Random();
int userId = rand.nextInt(9000000) + 1000000;
return Integer.toString(userId);
}
public static String getCurrentTimeInMillis() {
String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
logger.info("Current time:" + timeStamp);
return timeStamp.toString();
}
private static final Logger logger = LoggerFactory.getLogger(UatBaseClass.class);
public static Map<String,String> FINAL_CONFIG_MAP = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
protected static String clientID;
protected static String clientSecret;
protected static String cloudServer;
protected static String fbIosClientId;
protected static String fbIosClientSecret;
protected static String fbAndroidClientId;
protected static String fbAndroidClientSecret;
protected static String runningIosClientId;
protected static String runningIosClientSecret;
protected static String runningAndroidClientId;
protected static String runningAndroidClientSecret;
protected static String createUserBaseUrl;
protected static UrlFactory url;
protected static String env;
protected static String isApigeeUsed;
protected static String isBuildLatestFromBamboo;
protected static String mspEnv;
protected static String port;
protected static String protocol;
protected static String createUserFinalHost;
protected static String coreCommandLeaderBoardUrl;
protected static String coreQueryLeaderBoardUrl;
protected static String friendsLeaderboardsRouterUrl;
protected static CreateUserDeserializedObject primaryTestUser;
protected static String primaryUserAccessToken;
protected static String challengeElbUrl;
}
所以如果你的问题是多次调用初始化方法,我会选择单例模式。易于实施,不需要您像工厂那样改变工作方式。第一次调用会花费更长的时间进行初始化,接下来的调用只会注意到它已经完成了。正如您所说,我假设您已经熟悉这些模式并知道如何实现它们。
编辑:看到您发布的新代码后,我真的不认为所有这些变量都需要使用额外的内存,尤其是因为它们都是字符串并且您已经将它们全部放在地图中。只需将它们保留在地图上并使用枚举作为可能的键。一个访问函数就足够了。然后,如果您真的想直接访问,请添加从地图中获取的自定义访问方法。