简体   繁体   English

Java Map反模式?

[英]Java Map anti-pattern?

Edit: I've gotten a couple of answers that say what I already said in the question. 编辑:我已经得到了几个答案,说明我在问题中已经说过的话。 What I am really interested in is finding corroborating reference material. 我真正感兴趣的是找到确凿的参考资料。


I am looking at a code sample that more or less follows this pattern: 我正在看一个或多或少遵循这种模式的代码示例:

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

My feeling is that this is an anti-pattern. 我的感觉是,这是一种反模式。 What the coder should have done is create a class which can be returned, like this: 编码器应该做的是创建一个可以返回的类,如下所示:

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

This would be more type-safe, avoid over-generalizing a very specific problem, and be less prone to errors at runtime. 这将更加类型安全,避免过度概括非常具体的问题,并且在运行时不易出错。

Can anyone point me to any authoritative reference material which specifies that you should avoid this kind of pattern? 任何人都可以向我指出任何权威的参考资料,它指明你应该避免这种模式吗? Or, alternately, if it's actually a good pattern, please give justification. 或者,或者,如果它实际上是一个好的模式,请给出理由。

I think the point is the number of Lists is fixed . 我认为重点是列表的数量是固定的 Since you ensure the code uses 2 lists, the map is a little bit over-generalizing. 由于您确保代码使用2个列表,因此映射有点过于概括。

So ' class Result ' is better I think. 所以我认为“ 课程结果 ”更好。

I say it depends on the context. 我说这取决于具体情况。

If you return a map, the caller has to know the 'magic' keys "xList" and "yList" to get the actual data out of the map. 如果您返回地图,则调用者必须知道“魔术”键"xList""yList"以从地图中获取实际数据。 I mean magic as magic constants. 我的意思是魔法作为魔法常数。 (You could iterate over the map to find the magic keys, but that's just a trick.) By using the map you have actually hidden the data, making it harder to get what one wants (x- and yLists). (您可以遍历地图以查找魔术键,但这只是一个技巧。)通过使用地图,您实际上隐藏了数据,使得更难获得所需(x和yLists)。

The magic constants do not have to be so magically. 神奇的常数不一定非常神奇。 If "xList" and "yList" would be the table names in the database (or whatever external strings), then I would expect to get a mapping from table names to object lists. 如果"xList""yList"是数据库中的表名(或任何外部字符串),那么我希望得到从表名到对象列表的映射 Someone might add/rename/delete tables. 有人可能会添加/重命名/删除表。 (Or, maybe prettier, I would like to be able to query per table like getListFromTheDB("xList"); . ) (或者,可能更漂亮,我希望能够像每个表一样查询getListFromTheDB("xList");

In your code you got this method 在你的代码中你得到了这个方法

queryForListOfXItems();

That does smell like hard coded xList and yList. 这确实闻起来像硬编码的xList和yList。 That would thus (IMO) make a map a bad choice. 因此(IMO)将地图作为一个糟糕的选择。

I agree with you. 我同意你的看法。 Obviously the guy was lazy and used a Map to avoid creating a new class. 显然这个人很懒,并使用Map来避免创建一个新类。 The side effect is that the code that need to use getListsFromTheDB() will be less readable, and, as you mentionned, more error-prone. 副作用是需要使用getListsFromTheDB()的代码将不太可读,并且,正如您所提到的,更容易出错。

Of course, there is the alternative in which the caller creates the lists: 当然,还有调用者创建列表的替代方法:

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

I don't have any authoritative material, but my gut feeling is that, unless there's something more complex going on in the real code, using a Map this way doesn't bother me. 我没有任何权威材料,但我的直觉是,除非在实际代码中发生更复杂的事情,否则使用Map这种方式并不会让我烦恼。 The Result class feels a bit like overkill, actually. 实际上, Result类有点像矫枉过正。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM