Java Map反模式?

时间:2010-09-30 00:31:33

标签: java design-patterns list oop map

编辑:我已经得到了几个答案,说明我在问题中已经说过的话。我真正感兴趣的是找到确凿的参考资料。


我正在查看或多或少遵循此模式的代码示例:

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; }
}

这样更安全,避免过度概括非常具体的问题,并且在运行时不易出错。

有人能指出任何权威的参考资料,指明你应该避免这种模式吗?或者,或者,如果它实际上是一个好的模式,请给出理由。

4 个答案:

答案 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课有点像矫枉过正。