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


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


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


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


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


Абстракции в сознании


Кроме призмы восприятия, наши модели подвергаются ещё одному искажению: реальные сущности чрезвычайно сложны и имеют разные аспекты и параметры. При размышлении или разговоре о чём-то, всегда существует контекст, в котором существует модель. Причём иногда бывает так, что у собеседников этот контекст разный. И в довершение, наличие или отсутствие опыта (глобального) приводит к ещё большему изменению наших моделей в соответствие с этим опытом. В итоге у двух разных людей может быть очень разное восприятие одних и тех же сущностей реального мира.


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


Абстракции в разработке

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


Такая архитектура упрощает некоторые моменты в работе. Модульное тестирование сводится к написанию тестовых реализаций «соседних» абстракций и тестовых методов, сравнивающих вход и выход. Изоляция модулей позволяет безопасно проводить рефакторинг. Более того, если рефакторинг прошёл неудачно и всё сломалось, то откатывать придётся всего один модуль. Достаточно абстрагированный модуль может использоваться для схожих, но разных задач. При этом одна плохая реализация не будет влиять на работу других – изоляция говнокода.


Пример

Есть модуль для обработки входных данных, есть несколько вариантов их получения: из базы данных; из файла; по http. Решить эту задачу можно, выделив общий интерфейс для получения данных и сделав по реализации для каждого канала и канал данных для тестирования. Теперь один обработчик с помощью параметра «канал данных» может решать несколько схожих задач. А если выяснится, что одна из реализаций кривая, то её можно будет переделать на затрагивая другие модули.


Абстракций больше не надо


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


Во всём должен быть баланс. Для себя я вывел следующую памятку.


  • Если пишется большой и важный модуль – лучше расцеплять его.
  • Если модуль используется много и/или в разных местах – лучше скрыть его за абстракцией.
  • Если модуль должен распространяться как отдельная библиотека – лучше использовать абстракции.
  • Если возможно изменение алгоритмов или путей взаимодействия – лучше реализовывать взаимодействие абстракций.
  • Если класс используется в другом классе и нигде больше – можно подумать об их объединении или оставить как есть.
  • Если это маленькая «одноразовая» задача – лучше не заморачиваться с её усложнением.
  • Если это модуль, который скорее всего никогда не будет меняться – можно вывести его интерфейс и лучше оставить внутри всё как есть.

Итого


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

Комментарии (8)


  1. InterceptorTSK
    14.02.2019 19:48

    Программные интерфейсы — это, пожалуй, самая явная формализованная абстракция. Отсекается все лишнее и остаётся только «что оно делает» без «как оно делает».
    Не совсем так.
    Во-первых, формализации как таковой — интерфейсы никак не касаются вообще. Формализация — это вообще другая «опера».
    Во-вторых, вы пишете «остаётся только «что оно делает»», но это не так. Потому что в более широком логическом смысле интерфейс может быть и не реализован, и тут вы верно пишете «без «как оно делает»», но у всего этого тогда появляется третий смысл, в случае если интерфейс не реализован. И он явно следует, например, из английского образования «имен» интерфейсов, когда «приматывается» окончание -able. А оно обозначает допустимую возможность, и это самое важное в логике интерфейсного наследования.
    Пример: банальный интерфейс формы может быть реализован, и это тривиально;
    далее есть интерфейс формы, и он не реализован, и будет реализован возможно, или же не будет — это уже второй смысл;
    и третий смысл — ОН САМЫЙ ГЛАВНЫЙ — у объекта наследующего интерфейс — есть допустимая возможность (-able), которая как раз таки и обозначает, что объект ВПОЛНЕ МОЖЕТ БЫТЬ (-able) соотносится как-то с формой этими тремя смыслами.

    Третий смысл легко понимается как некий флаг:
    obj: ishapeable, icolorable

    При этом, если у интерфейсов нет ни одного метода (а логически так может быть), то интерфейсы тут говорят следующее: у объекта МОЖЕТ БЫТЬ (допустима возможность иметь, без реализации) форма и цвет, но какие они — не существенно…

    А потому, логически, интерфейс — это «самая» не явная абстракция, или как говорят «абстрактная абстракция».
    И т.д.

    пс: про каждый ваш абзац можно сильно долго писать как оно на самом деле, но извините, лень…


    1. dopusteam
      15.02.2019 09:15
      +1

      Во-первых, формализации как таковой — интерфейсы никак не касаются вообще. Формализация — это вообще другая «опера».

      Мне кажется, нужно определить, что значит формализация.
      Если принимать, что формализация — это возможность эту абстракцию потрогать\посмотреть, то я думаю, что автор имеет в виду, что интерфейс (я имею в виду не графический, а интерфейс как контракт), можно посмотреть и увидеть описание, что именно он делает.

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

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


  1. amarao
    14.02.2019 20:45
    +1

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

    При этом несовместимость базовых онтологических представлений (т.е. базовой иерархии понятий) чревата полным взаимным непониманием, а семантические различия в определении понятий (синонимы, или «каждый понимает по-своему») чревата конфликтами, причём очень трудными — ведь мы не можем объяснить другому человеку что мы имеем в виду не используя понятия нашей онтологической модели, и если у нас уже есть семантический конфликт, то он только усугубится.

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


  1. yavfast
    14.02.2019 22:04

    А потом приходит абстракция абстракций… и начинается апокалипсис абсолютный перфекционизм.


  1. moonster
    14.02.2019 22:19

    текут


  1. third112
    15.02.2019 03:43

    Программные интерфейсы — это, пожалуй, самая явная формализованная абстракция.
    Разрешите не согласиться. Классическая абстракция в программировании — это типы данных начиная с классического Паскаля (и раньше), потом добавились ОО классы.
    В итоге у двух разных людей может быть очень разное восприятие одних и тех же сущностей реального мира.
    Два грамотных программиста одинаково воспринимают тип Real, тип Integer и array [0..2] of integer.

    Вопрос: GUI — это программный интерфейс? Взять, нпр., объект «форма» (в смысле «окно»).
    у объекта МОЖЕТ БЫТЬ (допустима возможность иметь, без реализации) форма и цвет, но какие они — не существенно…
    Если не существенно, то форма формы и цвет реализуются средой по умолчанию. Но кому и когда не существенно? Кодеру, который пишет обработчики событий для этой формы, м.б. не важно красная форма или зеленая, но до тех пор пока не возникнет, нпр., задача: при неправильном клике пользователя форма должна краснеть, а при правильном зеленеть. Но, да, оттенки цвета кодера при этом волновать не будут. А вот дизайнер скажет: что зеленый слишком кислотный, а красный слишком блеклый.

    Т.о., учитывая приведенные примеры, смысл секции «Итого» не понял.


  1. sovetnik
    15.02.2019 05:08

    Посмотрите курс про теорию познания, несмотря на то, что там больше с точки зрения социологии и о программировании ни слова. postnauka.ru/courses/51323


  1. saboteur_kiev
    15.02.2019 15:36

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


    «вся эта туфта» это термин или осмысленная абстракция?

    Обобщение не всегда осмысленно. Это просто обобщение.