Java-карта анти-паттерн? - PullRequest
       5

Java-карта анти-паттерн?

5 голосов
/ 30 сентября 2010

Редактировать: Я получил пару ответов, которые говорят то, что я уже сказал в вопросе.Что меня действительно интересует, так это поиск подтверждающего справочного материала.


Я смотрю на пример кода, который более или менее следует этому шаблону:

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 ]

4 голосов
/ 30 сентября 2010

Я говорю, что это зависит от контекста.

Если вы возвращаете карту, вызывающая сторона должна знать «магические» клавиши "xList" и "yList", чтобы получить фактические данные из карты.Я имею в виду магию как магические константы.(Вы можете перебрать карту, чтобы найти волшебные ключи, но это всего лишь хитрость.) Используя карту, вы фактически скрыли данные, затрудняя получение того, что вы хотите (x- и yLists).

Магические константы не должны быть такими волшебными.Если бы "xList" и "yList" были бы именами таблиц в базе данных (или какими-либо внешними строками), тогда я ожидал бы получить отображение из имен таблиц в списки объектов.Кто-то может добавить / переименовать / удалить таблицы.(Или, может быть, красивее, я хотел бы иметь возможность запрашивать для каждой таблицы, например getListFromTheDB("xList");.)

В вашем коде вы получили этот метод

queryForListOfXItems();

Это пахнет жестко закодированнымxList и yList.Таким образом, это (ИМО) сделает карту плохим выбором.

4 голосов
/ 30 сентября 2010

Я думаю, что точка - это число списков фиксированное . Поскольку вы гарантируете, что код использует 2 списка, карта немного чрезмерно обобщает.

Так что ' класс Результат ' лучше, я думаю.

2 голосов
/ 30 сентября 2010

Я согласен с вами. Очевидно, парень был ленив и использовал карту, чтобы избежать создания нового класса. Побочным эффектом является то, что код, который должен использовать 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);
}
1 голос
/ 30 сентября 2010

У меня нет никакого авторитетного материала, но мое внутреннее чувство таково, что, если в реальном коде не происходит что-то более сложное, использование Map таким образом меня не беспокоит.На самом деле класс Result выглядит немного как излишнее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...