在基础 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;

}

所以如果你的问题是多次调用初始化方法,我会选择单例模式。易于实施,不需要您像工厂那样改变工作方式。第一次调用会花费更长的时间进行初始化,接下来的调用只会注意到它已经完成了。正如您所说,我假设您已经熟悉这些模式并知道如何实现它们。


编辑:看到您发布的新代码后,我真的不认为所有这些变量都需要使用额外的内存,尤其是因为它们都是字符串并且您已经将它们全部放在地图中。只需将它们保留在地图上并使用枚举作为可能的键。一个访问函数就足够了。然后,如果您真的想直接访问,请添加从地图中获取的自定义访问方法。