我有一个设计问题:让我以简单的例子来表达:
Public class A()
{
public static HashMap map = new HashMap();
public static String url = "default";
static {
getJson();
}
//url getters and setters are defined
public static getJson() {
//code which uses url to get json and populate hashmap
}
public string getresult(String key) {
//uses hashmap to send result.
}
我正在使用静态初始化块,因为我想只获取一次json。
public class B {
//这里我想更改url并调用getJson方法。如果我在设置url之前调用A.setUrl(),则调用A.getJson()方法,因为它在静态初始化块中。我可以先设置url然后调用getJson()。
//is this a bad design?
}
答案 0 :(得分:2)
这应该可行。添加新方法。
public static void getJson(String url) {
setUrl(url);
getJSon();
}
静态初始化器通常是一个坏主意,因为单元测试变得困难。
查看Misko Hevery's Guide to writing Testable Code。
您可以通过以下方式重新设计设计:
public class A {
//Add generics
private Map map = new HashMap();
public A(Map map){
this.map = map;
}
public String getresult(String key) {
//uses hashmap to send result.
}
}
//Helper Class
public class URLToJSon() {
//Add private constructor
public static Map convertUrlToJSon(String url) {
//do the conversion and return a hashmap
}
}
通过这种方式,我们可以遵循Single Responsibility Principle。
现在这两个类都是可测试的。
答案 1 :(得分:2)
是的,设计很糟糕:
如果您必须通过静态字段访问A
,我建议:
public class A {
private static Map<String, String> map;
/** must be invoked before get is first called */
public static void init(Map<String, String> newmap) {
map = newmap;
}
public static String get(String key) {
return map.get(key);
}
}
这就分散了使用数据和获取数据的担忧,允许每个数据被独立替换和测试。
还要考虑摆脱static
,因为它强制执行整个应用程序中只有一个地图同时存在,这是非常不灵活的。 (参见Ajay关于如何回答的第二个代码示例)
答案 2 :(得分:1)
网址设置在哪里?在构造函数中?如果是这样,只需执行
//Normal init stuff like set url here, followed by
if (! some check for if json is set) {
setJson();
}