Зачем загружать базу данных «Яблоки» в список, а не в ArrayList, Vector или LinkedList? - PullRequest
2 голосов
/ 07 февраля 2010

Я видел такой пример в тексте и не был уверен, почему они сделали это таким образом. Допустим, вы получаете кучу объектов Apple из базы данных:

List<Apple> appleList = (List<Apple>) db.getApples()

Зачем вам приводить к List<Apple> вместо одного из конкретных типов списка (ArrayList, Vector или LinkedList)?

Ответы [ 6 ]

5 голосов
/ 07 февраля 2010

Пользователь метода db.getApples() не должен заботиться о том, является ли это ArrayList, LinkedList и т. Д. Это деталь реализации.

Вы должны указывать конкретный тип структуры данных только при создании структуры данных. После этого вам следует обратиться к интерфейсу, который соответствует вашим потребностям.

Таким образом, вы можете без каких-либо проблем изменить конкретный тип структуры данных.

2 голосов
/ 07 февраля 2010

Эта вики-статья о Принципе замены Лискова и Принципе разделения интерфейсов может помочь вам понять, почему вы должны программировать для интерфейсов.

При работе между доменами, что является распространенным явлением в разработке EE, вам много раз не важно, какой тип коллекции используется. Вы чаще всего хотите просто извлечь что-то из него, выполнить итерацию или удалить что-то. Ничто из этого не требует знания того, с какой реализацией вы имеете дело. Это также облегчит переключение базовой реализации. Например, предположим, что я работаю над проектом и загружаю список элементов из базы данных в ArrayList. В другом месте кода я перебираю этот список:

class DBUtil {
    public static ArrayList<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}

... между тем ...

ArrayList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}

Теперь допустим, что я решил вместо этого использовать связанный список. Мне пришлось бы изменить метод, который загружал все из базы данных, а также код, который я использовал для его итерации:

class DBUtil {
    public static LinkedList<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}

... между тем ...

LinkedList<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}

Это было два изменения. Если бы я написал это изначально как:

class DBUtil {
    public static List<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}

... между тем ...

List<Item> items = DBUtil.getMeAllOfMyItems();
for (int i = 0; i < items.size(); i++) {
    // do something with item
}

Мне бы пришлось изменить только один метод, метод, в котором я возвращаю элементы из базы данных.

Еще лучше было бы изменить способ итерации элементов, чтобы использовать для каждого стиля:

class DBUtil {
    public static List<Item> getMeAllOfMyItems() {
         return items; // load from database whatever...
    }
}

... между тем ...

List<Item> items = DBUtil.getMeAllOfMyItems();
for (Item i : items) {
    // do something with item
}

Теперь, если бы я захотел, я мог бы даже изменить еще больше реализации, и пока все, что я использую, реализует Iterable, мне даже не важно, какой тип Collection использует базовая система.

Вы должны стремиться сделать вещи как можно более общими с намерением, что вам не нужно менять 3 или 4 файла из-за небольшого изменения в другом месте.

0 голосов
/ 07 февраля 2010

Поскольку в Java вы должны кодировать интерфейсы , а не реализации .

Это позволяет автору кода библиотеки выбрать наиболее подходящую реализацию списка, и вам все равно. Если вы это сделаете, скопируйте список в реализацию списка с нужными вам свойствами.

Например, если вам нужно получить O (1) раз, скопируйте в ArrayLIst.

0 голосов
/ 07 февраля 2010

Обычно лучше работать с общим интерфейсом. Таким образом, базовая реализация может быть оставлена, чтобы решить, какой конкретный тип лучше всего подойдет для этой работы. Это также облегчает тестирование с использованием макетов.

0 голосов
/ 07 февраля 2010

Большую часть времени вы не знаете точную реализацию List, возвращаемую API, к которому принадлежит db. Это может быть либо одна из стандартных реализаций в Java SE, либо пользовательская реализация API.

0 голосов
/ 07 февраля 2010

List - это просто интерфейс, а ArrayList или LinkedList - реализации. Согласно Joshua Bloch - Effective Java (Item 18; 19), здесь всегда лучше использовать интерфейсы. Таким образом, вы можете легко переключать реализации.

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