编辑:我已经得到了几个答案,说明我在问题中已经说过的话。我真正感兴趣的是找到确凿的参考资料。
我正在查看或多或少遵循此模式的代码示例:
Map<String, List> getListsFromTheDB() {
Map<String, List> lists = new HashMap<String, List>();
//each list contains a different type of object
lists.put("xList", queryForListOfXItems());
lists.put("yList", queryForListOfYItems());
return lists;
}
void updateLists() {
Map<String, List> lists = getListsFromTheDB();
doSomethingWith(lists.get("xList"));
doSomethingWith(lists.get("yList"));
}
我的感觉是这是一种反模式。编码员应该做的是创建一个可以返回的类,如下所示:
class Result {
private final List<X> xList;
private final List<Y> yList;
public Result(xList, yList) {
this.xList = xList;
this.yList = yList;
}
public List<X> getXList() { xList; }
public List<Y> getYList() { return yList; }
}
这样更安全,避免过度概括非常具体的问题,并且在运行时不易出错。
有人能指出任何权威的参考资料,指明你应该避免这种模式吗?或者,或者,如果它实际上是一个好的模式,请给出理由。
答案 0 :(得分:4)
我认为重点是列表的数量是固定。由于您确保代码使用2个列表,因此映射有点过于概括。
所以' class Result '我认为更好。
答案 1 :(得分:4)
我说这取决于具体情况。
如果您返回地图,则来电者必须知道“魔术”键"xList"
和"yList"
才能从地图中获取实际数据。我的意思是魔法作为魔法常数。 (您可以遍历地图以查找魔术键,但这只是一个技巧。)通过使用地图,您实际上隐藏了数据,使得更难获得所需(x和yLists)。
魔术常数不一定非常神奇。如果"xList"
和"yList"
是数据库中的表名(或任何外部字符串),那么我希望从表名到对象列表获得映射。有人可能会添加/重命名/删除表。 (或者,可能更漂亮,我希望能够像getListFromTheDB("xList");
一样查询每个表。)
在你的代码中你得到了这个方法
queryForListOfXItems();
这确实闻起来像硬编码的xList和yList。因此(IMO)将地图作为一个糟糕的选择。
答案 2 :(得分:2)
我同意你的看法。 显然这个人很懒,并使用Map来避免创建一个新类。 副作用是需要使用getListsFromTheDB()的代码将不太可读,并且正如您所提到的,更容易出错。
当然,调用者可以创建列表:
void fillFromTheDB(List<X> xList, List<Y> yList) {
//each list contains a different type of object
xList.addAll(queryForListOfXItems());
yList.addAll(queryForListOfYItems());
}
void updateLists() {
List<X> xList = new ArrayList<X>();
List<Y> yList = new ArrayList<Y>();
fillFromTheDB(xList, yList);
doSomethingWith(xList);
doSomethingWith(yList);
}
答案 3 :(得分:1)
我没有任何权威材料,但我的直觉是,除非在实际代码中发生更复杂的事情,否则使用Map
这种方式并不会让我烦恼。实际上Result
课有点像矫枉过正。