Значение утечки абстракции? - PullRequest
74 голосов
/ 07 октября 2010

Что означает термин «негерметичная абстракция»? (Пожалуйста, объясните на примерах. Мне часто трудно ухватиться за простую теорию.)

Ответы [ 10 ]

85 голосов
/ 23 июня 2011

Вот пример meatspace :

В автомобилях есть абстракции для водителей.В чистом виде руль, акселератор и тормоз.Эта абстракция скрывает много деталей о том, что находится под капотом: двигатель, кулачки, ремень ГРМ, свечи зажигания, радиатор и т. Д.

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

Это на самом деле весьма примечательно ... 16-летний или 80-летний может управлять этой сложной машинойбез особого знания о том, как это работает внутри!

Но есть утечки.Коробка передач - маленькая утечка.В автоматической трансмиссии вы можете почувствовать, что машина на мгновение теряет мощность, когда она переключает передачи, в то время как в вариаторах вы чувствуете плавный крутящий момент на всем протяжении.

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

44 голосов
/ 07 октября 2010

Это просто означает, что ваша абстракция раскрывает некоторые детали реализации или что вам необходимо знать о деталях реализации при использовании абстракции. Этот термин относится к Джоэлю Спольски , около 2002 года. Дополнительную информацию см. В Википедии статья .

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

12 голосов
/ 07 октября 2010

В Википедии есть довольно хорошее определение для этого

Утечка абстракции относится к любой реализованной абстракции, предназначенной для уменьшения (или скрытия) сложности, когда базовые детали не полностью скрыты

Или, другими словами, для программного обеспечения вы можете наблюдать детали реализации функции через ограничения или побочные эффекты в программе.

В качестве быстрого примера можно привести замыкания C # / VB.Net и их неспособность получить параметры ref / out. Причина, по которой они не могут быть захвачены, заключается в деталях реализации того, как происходит процесс подъема. Это не значит, что есть лучший способ сделать это.

11 голосов
/ 07 октября 2010

Вот пример, знакомый разработчикам .NET: класс ASP.NET Page пытается скрыть детали HTTP-операций, в частности, управление данными формы, чтобы разработчикам не приходилось иметь дело с опубликованными значениями (потому что этоавтоматически сопоставляет значения формы с серверными элементами управления).

Но если вы выходите за рамки самых простых сценариев использования, абстракция Page начинает протекать и становится трудно работать со страницами, если вы не понимаете детали реализации класса.

Одним из распространенных примеров является динамическое добавление элементов управления на страницу - значение динамически добавленных элементов управления не будет отображаться для вас, если вы не добавите их в как раз в нужное время : перед базовымДвижок отображает входящие значения формы в соответствующие элементы управления.Когда вы должны это узнать, у абстракции утечка .

7 голосов
/ 07 октября 2010

Ну, в некотором смысле это чисто теоретическая вещь, хотя и не маловажная.

Мы используем абстракции, чтобы упростить понимание.Я могу оперировать строковым классом на каком-то языке, чтобы скрыть тот факт, что я имею дело с упорядоченным набором символов, которые являются отдельными элементами.Я имею дело с упорядоченным набором символов, чтобы скрыть тот факт, что я имею дело с числами.Я имею дело с числами, чтобы скрыть тот факт, что я имею дело с 1 и 0.

Утечка абстракции - это та, которая не скрывает детали, которые она должна скрывать.Если вызвать string.Length для 5-символьной строки в Java или .NET, я мог получить любой ответ от 5 до 10, из-за деталей реализации, где то, что эти языки называют символами, на самом деле являются точками данных UTF-16, которые могут представлять 1 или.5 персонажа.Абстракция просочилась.Однако отсутствие утечки означает, что для определения длины потребуется либо больше места для хранения (для хранения реальной длины), либо для перехода от O (1) к O (n) (чтобы определить реальную длину).Если я забочусь о реальном ответе (часто это не так), вам нужно работать над знанием того, что на самом деле происходит.

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

5 голосов
/ 07 октября 2010

Я продолжу в том же духе приводить примеры с использованием RPC.

В идеальном мире RPC вызов удаленной процедуры должен выглядеть как вызов локальной процедуры (или так обстоит дело). Он должен быть полностью прозрачным для программиста, чтобы при вызове SomeObject.someFunction() он не имел представления, хранятся ли SomeObject (или просто someFunction в этом отношении) локально и выполняются или хранятся и выполняются удаленно. Теория гласит, что это делает программирование проще.

Реальность другая, потому что существует ОГРОМНАЯ разница между вызовом локальной функции (даже если вы используете самый медленный интерпретируемый язык в мире) и:

  • вызов через прокси-объект
  • сериализация ваших параметров
  • подключение к сети (если еще не установлено)
  • передача данных на удаленный прокси
  • удаленный прокси восстанавливает данные и вызывает удаленную функцию от вашего имени
  • сериализация возвращаемых значений
  • передача возвращаемых значений на локальный прокси
  • повторная сборка сериализованных данных
  • возврат ответа от удаленной функции

Только за время разница в величины порядка трех (или более!). Эти три + порядков будут иметь огромное значение в производительности, что сделает вашу абстракцию утечки вызова процедуры довольно очевидной в первый раз, когда вы ошибочно воспримете RPC как реальный вызов функции. Кроме того, реальный вызов функции, исключающий серьезные проблемы в вашем коде, будет иметь очень мало точек сбоя за пределами ошибок реализации. У вызова RPC есть все следующие возможные проблемы, которые будут рассматриваться как случаи отказов сверх того, что вы ожидаете от обычного локального вызова:

  • вы не сможете создать экземпляр своего локального прокси
  • вы не сможете создать экземпляр удаленного прокси
  • прокси не может подключиться
  • отправленные вами параметры могут не сделать его целым или вовсе
  • возвращаемое значение, которое отправляет удаленное устройство, может не сделать его целым или вовсе

Так что теперь ваш RPC-вызов, который "подобен локальному вызову функции", имеет целый набор дополнительных условий сбоя, с которыми вам не приходится сталкиваться при выполнении локальных вызовов функции. Абстракция снова просочилась, еще сильнее.

В конце концов, RPC - плохая абстракция, потому что она протекает как сито на каждом уровне - при успешном и неудачном завершении обоих.

3 голосов
/ 07 октября 2010

Пример в примере django ORM «многие ко многим» :

Обратите внимание в примере использования API, что вам необходимо .save () базовый объект Article a1, прежде чем вы сможетедобавить объекты Publication в атрибут многие-ко-многим.И обратите внимание, что обновление атрибута «многие ко многим» немедленно сохраняет в базовой базе данных, тогда как обновление атрибута в единственном числе не отражается в БД до тех пор, пока не будет вызван .save ().

Абстракция заключается в том, что мы работаем с графом объектов, где атрибуты с одним значением и атрибуты с несколькими значениями являются просто атрибутами.Но реализация в виде хранилища данных, поддерживаемого реляционной базой данных, протекает ... поскольку система целостности RDBS появляется через тонкий слой интерфейса объекта.

0 голосов
/ 10 октября 2018

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

Например, рассмотрим запрос SQL:

SELECT id, first_name, last_name, age, subject FROM student_details;

И это альтернатива:

SELECT * FROM student_details;

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

Это тривиальный пример, но в итоге он возвращается к цитате Джоэла Спольски:

Все нетривиальные абстракции, в некоторой степени, негерметичны.

В какой-то момент, когда вы достигнете определенного масштаба в вашей работе, вы захотите оптимизировать работу вашей БД (SQL). Для этого вам нужно знать, как работают реляционные базы данных. Вначале он был абстрагирован от вас, но он протекает. Вы должны изучить это в какой-то момент.

0 голосов
/ 13 июля 2018

Утечка абстракции - это все о состоянии инкапсуляции.очень простой пример неплотной абстракции:

$currentTime = new DateTime();

$bankAccount1->setLastRefresh($currentTime);
$bankAccount2->setLastRefresh($currentTime);
$currentTime->setTimestamp($aTimestamp);

class BankAccount {
    // ...

    public function setLastRefresh(DateTimeImmutable $lastRefresh)
    {
        $this->lastRefresh = $lastRefresh;
    } }

и правильный путь (не пропускающая абстракция):

class BankAccount
{
    // ...

    public function setLastRefresh(DateTime $lastRefresh)
    {
        $this->lastRefresh = clone $lastRefresh;
    }
}

подробное описание здесь .

0 голосов
/ 24 февраля 2017

Предположим, у нас есть следующий код в библиотеке:

Object[] fetchDeviceColorAndModel(String serialNumberOfDevice)
{
    //fetch Device Color and Device Model from DB.
    //create new Object[] and set 0th field with color and 1st field with model value. 
}

Когда потребитель вызывает API, он получает Object [].Потребитель должен понимать, что первое поле массива объектов имеет значение цвета, а второе поле является значением модели.Здесь абстракция просочилась из библиотеки в код потребителя.

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

DeviceColorAndModel fetchDeviceColorAndModel(String serialNumberOfTheDevice)
{
    //fetch Device Color and Device Model from DB.
    return new DeviceColorAndModel(color, model);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...