Чи є інтерфейс списку герметичною абстракцією?


9

Якщо у мене є змінна, що містить, Listвона може містити об'єкти безлічі різних типів, наприклад, ArrayListабо LinkedList. Різниця між a LinkedListі an ArrayListдосить велика. Велика поведінка методів O значно відрізняється. Наприклад, сортування, Listа потім його використання для здійснення двійкових пошуків - це цілком нормально, ArrayListале це не має сенсу для LinkedList.


Що означає "великий О"?
Tulains Córdova

Відповіді:


25

Я б не сказав цього.

Витікаюча абстракція - це те, що змушує вас мати справу з деталями впровадження, які слід абстрагувати. Але продуктивність завжди відрізняється між реалізаціями, тож якщо ви вважаєте, що це протікає, то відсутні абстракції, що не протікають.

Якщо щось задекларовано як Listбез додаткової документації, слід розуміти, що гарантій щодо продуктивності просто немає, і якщо ви збираєтесь робити з цим що-небудь залежне від продуктивності, вам слід зробити копію та працювати з цим.

Крім того , не варто забувати , що є ще більш загальний інтерфейс , який часто буває досить функціональності і не спокушати вас , щоб зробити так багато припущень про продуктивності: Collection.


9
Існує ще більш загальний інтерфейс , який часто буває досить функціональності: Iterable.
emory

Очікуються відмінності в ефективності між різними реалізаціями. Наприклад, існують відмінності між Vector і ArrayList, але операція з отримання на LinkedList просто здається дивною.
Паллінг

17

Всі нетривіальні абстракції, певною мірою, є негерметичними. Однак я не впевнений, що це стосується і тут. :-)

Абстракції стосуються поведінки. Якщо поведінка не визначає конкретну продуктивність (чого Listне має Java ), це деталізація реалізації - тобто не має значення.

Java не дозволяє вказувати мінімальну продуктивність для інтерфейсів поза документацією, і я не знаю жодних мов, які це виконують - компілятору це було б надзвичайно важко (неможливо?). Я бачу пару варіантів, якщо продуктивність викликає занепокоєння:

  1. Документуйте його в класі / інтерфейсі, до якого буде належати екземпляр списку.
  2. Створіть новий інтерфейс - наприклад BinarySearchPerformantList(yuck!) - який визначає вимоги до продуктивності різних методів.

Варіант 2, мабуть, краща абстракція, але має додаткові накладні витрати.


1
+1. Технічно так, Список є витікаючою абстракцією , але тоді це також Об'єкт для приховування складності, пов'язаної з використанням equalsдля порівняння об'єктів.
Ніл

2
@Neil Я думаю, що це дискусійно ... Оскільки абстракція не згадує про ефективність, я не думаю, що вона провалюється в цьому випадку (як я вже стверджував). Я б сказав, що якщо ви думаєте про продуктивність, вам потрібна інша / вужча абстракція. Відредагуємо, щоб згадати про це.
vaughandroid

Це залежить від того, що ти приховуєш. Чи є складність у використанні чи вона полягає у використанні та реалізації пам'яті? Тому що якщо це абстрактний клас, одна чи кілька цих складностей так чи інакше приховуються.
Ніл

Я грав багато років назад реалізації варіації варіанти 2 з використанням маркерів інтерфейсів , як LinearSpaceі , LogarithmicTimeа потім оголосити класи , як public class BinarySearch : ISearchStrategy<T>, LogarithmicTime. Інші класи можуть приймати такі параметри, як public T find<T, S>(IList<T> list, S strategy) where S : ISearchStrategy<T>, LogarithmicTime { }примусові обмеження продуктивності.
Лукас

2
Якщо ми підемо за статтею Джоела Спольського, я думаю, що це "певною мірою, непрохідне". Дивіться наступну цитату із статті: "Якщо ви змусили системних адміністраторів вашої компанії, і вони покарали вас, підключивши вас до перевантаженого хабу, пройдуть лише деякі ваші IP-пакети, і TCP запрацює, але все буде бути дуже повільним "Я думаю, що це стосується
програму Amish

4

У Java існує інтерфейс RandomAccess, який визначається як список із загальним постійним часом випадкового доступу (O (1) отримати, поставити тощо). Якщо ви вважаєте, що для вашого модуля потрібен список із тими характеристиками продуктивності, подумайте про використання RandomAccessзамість List. Якщо ви не відчуваєте необхідності вносити ці зміни (а це мало хто робить), можливо, Список не такий проникливий.


1

Ви маєте рацію, Список - це витікаюча абстракція. STL використовує ідею концепцій для моделювання цієї конкретної проблеми. Щоб використати ваш приклад, ArrayListмодель ітератора випадкового доступу, тоді як LinkedList моделює ітератор вперед . Різні концепції мають різні вимоги до продуктивності, що робить їх відповідними для різних алгоритмів .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.