// codeart.ru / Теория программирования / Приводим в порядок «уровни абстракции» Форум

Приводим в порядок «уровни абстракции» rss подписка

Автор: Evgeniy Sergeev

В программировании очень часто употребляются такое понятие как «повышение уровня абстракции». Мне кажется, что настало время поговорить об этом термине и разобраться что такое уровни абстракции и как их можно повысить. Далее я расскажу все, что знаю и чего не знаю.

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

Для начала немного воды

Сама по себе абстракция — это способ взять под контроль многообразие предметной области и получить модели, пригодные для решения поставленных задач.
Результат достигается путем выполнения трех простых действий: выделением, объединением и сокрытием важных характеристик сущностей предметной области. При этом все изменения вносятся через интерфейс управления данными.
Все несущественное откидываем и не вспоминаем, до тех пор пока не придет нужное время.

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

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

Понятие абстракции используется во многих инженерных специальностях. У программистов есть своя специфика работы, связанная с использованием основного инструмента разработки — языка программирования.

Пример неправильной декомпозиции

пирамида уровней абстракции

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

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

Для примера разберем простой случай для абстрактного языка программирования.

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

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

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

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

Все эти уровни мы упаковываем в пирамидку и получаем довольно красивую картинку.

Горькая правда

Картинка кажется простой, логичной и правильной. Но как раз правильной она не является. Мы не можем решать прикладные задачи, не используя возможностей, которые представляет язык программирования, а значит у нас есть связь между вершиной и основанием пирамиды. Поэтому наш слоеный пирог должен выглядеть по-другому. Но как?

Давайте разбираться.

Первое, что приходит в голову — мы на картинку затянули не уровни абстракции, а что-то другое.

Начнем с базовых типов и конструкций языка. Являются ли они абстракциями?

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

Далее уровень стандартных библиотек. Являются ли они уровнем абстракции?

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

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

Связь с более низкими уровнями не дает подняться вверх. Поэтому этот уровень в лучшем случае находится на том же уровне что примитивы языка.

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

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

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

правильное представление уровней абстракции

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

Выводы

Чтобы совсем упростить задачу приведу конкретные выводы о том как следует понимать понижение и повышение уровней абстракции.

0. Уровни абстракции могут повышаться как на уровне данных, так и на уровне методов (функций)

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

Стоит нам в производном классе напрямую обратиться к более низким уровням абстракции, как вместо повышения мы понижаем его уровень;

2. Уровень абстракции можно повысить за счет композиции, но только при условии, что мы используем абстракции только из прилегающего уровня;

3. Использование базовых типов и стандартных библиотек автоматически ставит абстракцию на первый уровень;

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

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

Leave a Reply

« »