Парадигма программирования

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 20:42, 11 января 2019.

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

Парадигма (философия науки) – устоявшаяся система научных взглядов, в рамках которой ведутся исследования (Т. Кун).

Парадигма определяется:

  • вычислительной моделью
  • базовой программной единицей(-ами)
  • методами разделения абстракций [Источник 1]

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

История

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

Термин «парадигма программирования» впервые применил в 1978 году Роберт Флойд в своей лекции лауреата премии Тьюринга. Флойд отмечает, что в программировании можно наблюдать явление, подобное парадигмам Куна, но, в отличие от них, парадигмы программирования не являются взаимоисключающими: если прогресс искусства программирования в целом требует постоянного изобретения и усовершенствования парадигм, то совершенствование искусства отдельного программиста требует, чтобы он расширял свой репертуар парадигм.

Таким образом, по мнению Роберта Флойда, в отличие от парадигм в научном мире, описанных Куном, парадигмы программирования могут сочетаться, обогащая инструментарий программиста.

Важно отметить, что парадигма программирования не определяется однозначно языком программирования; практически все современные языки программирования в той или иной мере допускают использование различных парадигм. Так на языке Си, который не является объектно-ориентированным, можно работать в соответствии с принципами объектно-ориентированного программирования, хотя это и сопряжено с определёнными сложностями; функциональное программирование можно применять при работе на любом императивном языке, в котором имеются функции (для этого достаточно не применять присваивание). [Источник 2]

Разновидности парадигмы

Парадигма программирования не определяется однозначно языком программирования; практически все современные языки программирования в той или иной мере допускают использование различных парадигм.

Так на языке Си, который не является объектно-ориентированным, можно работать в соответствии с принципами объектно-ориентированного программирования, хотя это и сопряжено с определёнными сложностями; функциональное программирование можно применять при работе на любом императивном языке, в котором имеются функции (для этого достаточно не применять присваивание), и т.д.

Императивное программирование

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

Вычислительная модель - машина Тьюринга.

Основные механизмы управления/абстракции:

  • Последовательное исполнение команд
  • Ветвление
  • Безусловный переход
  • Вызов подпрограммы (иногда)

Элементарные единицы модульности - отсутствуют. [Источник 3]

Структурное программирование

Струк­тур­ные парадигмы программирования на­це­ле­ны на со­кра­ще­ние вре­ме­ни раз­ра­бот­ки и уп­ро­ще­ние под­держ­ки про­грамм за счёт ис­поль­зо­ва­ния блоч­ных опе­ра­то­ров и под­про­грамм. От­ли­чительной чер­той струк­тур­ных про­грамм яв­ля­ет­ся от­каз от опе­ра­то­ра пе­ре­хо­да (goto).

Вычислительная модель - машина Тьюринга.

Основные механизмы управления/абстракции:

  • Последовательное исполнение команд
  • Ветвление
  • Цикл
  • Вызов подпрограммы
  • Лексический контекст

Элементарные единицы модульности:

  • Подпрограмма с изолированным лексическим

контекстом

Объектно-ориентированное программирование

В дан­ной парадигме программирования про­грам­ма раз­би­ва­ет­ся на объ­ек­ты – струк­ту­ры дан­ных, со­стоя­щие из по­лей, опи­сы­ваю­щих со­стоя­ние, и ме­то­дов – под­про­грамм, при­ме­няе­мых к объ­ек­там для изме­не­ния или за­про­са их со­стоя­ния. В боль­шей час­ти объ­ект­но ори­ен­ти­ро­ван­ных парадигмах для опи­са­ния объ­ек­тов ис­поль­зу­ют­ся клас­сы, объ­ек­ты бо­лее вы­со­ко­го по­ряд­ка, опи­сы­ваю­щие струк­ту­ру и опе­ра­ции, свя­зан­ные с объ­ек­та­ми. В ка­че­ст­ве бо­лее ча­ст­ной парадигмы по от­но­ше­нию к объ­ект­но ори­ен­ти­ро­ван­ной вы­де­ля­ют про­то­типно ори­ен­ти­ро­ван­ную парадигму. В от­ли­чие от ос­но­ван­ных на клас­сах объ­ект­но ори­ен­ти­ро­ван­ных сис­тем, в про­то­тип­но ори­ен­ти­ро­ван­ных сис­те­мах по­ня­тие клас­сов не ис­поль­зу­ет­ся, а но­вые пе­ре­мен­ные объ­ек­ты соз­да­ют­ся пу­тём ко­пи­ро­ва­ния су­ще­ст­вую­щих про­то­ти­пов. К язы­кам, под­дер­жи­ваю­щим объ­ект­но ори­ен­ти­ро­ван­ную парадигму программирования , от­но­сят­ся си++, Common Lisp (так­же со­дер­жит эле­мен­ты функ­цио­наль­ной парадигмы), джа­ва, джа­ва-скрипт (прототип­но ори­ен­ти­ро­ван­ная мо­дель).

Вычислительная модель - машина Тьюринга

Основные механизмы управления/абстракции:

  • Объект
  • Класс
  • Иерархии классов/объектов
  • Полиморфизм

Элементарные единицы модульности - класс

Функциональное программирование

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

Вычислительная модель - λ-исчисление

Основные механизмы управления/абстракции:

  • Чистая функция, как объект первого класса
  • Вызов функции (в т.ч. рекурсивный)
  • Лексический контекст, замыкание

Элементарные единицы модульности:

  • Функция (в т.ч. высшего порядка, обобщенная и т.д.)

Основные концепции:

Неподвижное состояние объектов

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

Чистая функция (pure function) – функция не имеющая побочных эффектов, т.е. единственным эффектом ее применение является порождение результата, зависящего только от аргументов. [Источник 3]

Логическое программирование

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

Логическое программирование начинает свой отсчет времени с конца 60-х годов XX века, когда Корделл Грин предложил использовать резолюцию как основу логического программирования. Алан Колмеро создал язык логического программирования Prolog в 1971 году. Логическое программирование пережило пик популярности в середине 80-х годов XX века, когда оно было положено в основу проекта разработки программного и аппаратного обеспечения вычислительных систем пятого поколения.

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

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

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

Нелинейность структуры программы является особенностью декларативного подхода и, строго говоря, представляет собой оригинальную особенность, а не объективный недостаток. [Источник 4]

Подходы и приёмы

Далее будут представлены более подробно подходы и приемы парадигмы программирования:

  • Структурное программирование
  • Процедурное программирование
  • Обобщённое программирование
  • Доказательное программирование
  • Порождающее программирование
  • Аспектно-ориентированное программирование
  • Рекурсия
  • Автоматное программирование
  • Событийно-ориентированное программирование
  • Компонентно-ориентированное программирование
  • Грамотное программирование

Структурное программирование

Cтруктурное программирование воплощает принципы системного подхода в процессе создания и эксплуатации программного обеспечения ЭВМ. В основу структурного программирования положены следующие достаточно простые положения:

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

Фундаментом структурного программирования является теорема о структурировании. Эта теорема устанавливает, что, как бы сложна ни была задача, схема соответствующей программы всегда может быть представлена с использованием ограниченного числа элементарных управляющих структур. Базовыми элементарными структурами являются структуры: следование, ветвление и повторение (цикл), любой алгоритм может быть реализован в виде композиции этих трех конструкций. [Источник 5]

Обобщённое программирование

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

Процедурное (алгоритмическое) программирование

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

Преимущества и недостатки процедурного программирования: Среди недостатков ПП можно назвать следующие:

  • Риск возникновения множества ошибок при работе над большим проектом. Приходится писать много процедур, и это не может не сказаться на чистоте и работоспособности кода.
  • Все данные процедуры доступны только внутри нее. Их нельзя вызвать из другого места программы и при необходимости придется писать аналогичный код. А это уже противоречит одному из основополагающих принципов программирования, который звучит как Don’t Repeat Yourself (Не повторяйся).
  • Сложность изучения для начинающих. Этот недостаток может кому-то показаться притянутым за уши, но простая статистика свидетельствует, что процедурное программирование для большинства новичков дается сложнее, чем объектно-ориентированное. Преимущества:
  • Любая процедура (функция) может быть вызвана неограниченное количество раз.
  • Возможность оперативно решить задачу, в которой отсутствует сложная иерархия. [Источник 7]

Доказательное программирование

Доказательное программирование — это составление программ с доказательством их правильности. Сложность составления и доказательства правильности алгоритмов и программ состоит в следующем.

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

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

Существуют два подхода к проверке программ — прагматический и доказательный. При прагматическом подходе проверка программ выполняется на ЭВМ путем тестирования.

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

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

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

Таким образом, прагматический подход чреват созданием программ, содержащих ошибки даже после «завершения» отладки, что и наблюдается практически во всех больших программах для ЭВМ. [Источник 8]

Порождающее программирование

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

Порождающее программирование фокусирует внимание не на уникальных продуктах (объектах), а на семействах программных систем (классах объектов). Таким образом, порождающее программирование имеет огромное сходство с теорией универсальных и интегративных моделей, применяемых для синтеза объектов, и являющихся моделями не отдельно взятого объекта, а моделями всех объектов, принадлежащих рассматриваемому классу (моделью семейства объектов или систем). [Источник 9]

Аспектно-ориентированное программирование

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

Аспектно-ориентированное программирование выросло из осознания того, что в типовых программах на объектно-ориентированных языках часто представлена функциональность, которая не вмещается естественно в один или даже в несколько тесно связанных программных модулей. Такую функциональность называют "сквозной" (англ. scattered, разбросанная или tangled, переплетённая), её реализация рассыпана по различным модулям программы. Сфера действия АОП охватывает пространство проблем, непосильных для объектно-ориентированных и процедурных языков. Оно предлагает элегантные пути для реализации задач, решение которых сдерживалось из-за фундаментальных ограничений программирования.

АОП дополняет объектно-ориентированное программирование, обогащая его другим типом модульности, который позволяет локализовать код реализации "сквозной" логики в одном модуле. Такие модули обозначаются термином аспекты. За счет отделения аспектно-ориентированного кода работа со "сквозными" отношениями упрощается. Аспекты в системе могут изменяться, вставляться, удаляться на этапе компиляции и, более того, повторно использоваться. [Источник 10]

Рекурсия

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

У рекурсии должно быть условие остановки — Базовый случай (иначе также как и цикл рекурсия будет работать вечно — infinite). Это условие и является тем случаем к которому рекурсия идет (шаг рекурсии). При каждом шаге вызывается рекурсивная функция до тех пор пока при следующем вызове не сработает базовое условие и произойдет остановка рекурсии(а точнее возврат к последнему вызову функции). Всё решение сводится к решению базового случая. В случае, когда рекурсивная функция вызывается для решения сложной задачи (не базового случая) выполняется некоторое количество рекурсивных вызовов или шагов, с целью сведения задачи к более простой. И так до тех пор пока не получим базовое решение. [Источник 11]

Автоматное программирование

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

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

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

При этом необходимо отметить, что в автоматном программировании отладка проводится путем протоколирования в терминах автоматов. [Источник 12]

Событийно-ориентированное программирование

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

Структура программы в событийном программировании следующая: главная часть программы представляет собой один бесконечный цикл, который опрашивает windows, следя за тем, не появилось ли новое сообщение. При его обнаружении вызывается программа, отвечающая за обработку соответственного сообщения. Цикл опроса будет продолжаться, пока не будут получены сообщения завершения работы.

События могут быть пользовательскими, системными и программными, которые генерируются самой программой. [Источник 13]

Компонентно-ориентированное программирование

Компонентно-ориентированное программирование (англ. component-oriented programming, COP) — парадигма программирования, существенным образом опирающаяся на понятие компонента — независимого модуля исходного кода программы, предназначенного для повторного использования и развёртывания и реализующегося в виде множества языковых конструкций (например, «классов» в объектно-ориентированных языках программирования), объединённых по общему признаку и организованных в соответствии с определёнными правилами и ограничениями. [Источник 14]

Грамотное программирование

Грамотное, или литературное, программирование – это экстремальная технология самодокументируемого кода, предложенная знаменитым специалистом в вычислительной технике Дональдом Кнутом. Он написал книгу под этим названием, в которой и описал эту технологию (Knuth 92). Это радикальная альтернатива традиционной модели программирования, хотя некоторые считают, что период грамотного программирования был крупной неудачей в карьере Д. Кнута.

Лежащая в основе идея проста: нужно писать не программу, а документ. Язык документации тесно привязан к языку программирования. Ваш документ в основном описывает то, что программируется, но при этом допускает компиляцию в нужную программу. Таким образом, исходный код – это документация, и наоборот. [Источник 15]

Источники

  1. Парадигма программирования. [2018—2018].URL: http://ccfit.nsu.ru/~shadow/DT6/pdf/lecture_2_1_paradigms.pdf (дата обращения: 02.12.2018).
  2. Парадигма программирования // Albest. [2000—2018]. Дата обновления: 16.12.2014.URL: https://otherreferats.allbest.ru/programming/00498870_0.html (дата обращения: 02.12.2018).
  3. 3,0 3,1 Парадигмы программирования. [2018—2018].URL: http://ccfit.nsu.ru/~shadow/DT6/pdf/lecture_2_1_paradigms.pdf (дата обращения: 02.12.2018).
  4. Логическое программирование // StudFiles [2015—2019].URL: https://studfiles.net/preview/2975967/page:42/ (дата обращения: 11.01.2019).
  5. Структурное программирование // StudFiles . [2015—2019].URL:https://studfiles.net/preview/4290050/ (дата обращения: 11.01.2019).
  6. Обобщенное программирование // StudFiles [2015—2019].URL:https://studfiles.net/preview/2081779/page:2/ (дата обращения: 11.01.2019).
  7. Процедурное программирование // Чудо Саикт [2018—2019].URL: https://saikt-online.ru/procedurnoe-programmirovanie-protiv-obektno-orientirovannogo/ (дата обращения: 02.12.2018).
  8. Доказательное программирование // LawBooks.News. [2018—2019].URL: http://lawbooks.news/telekommunikatsionnyie-sistemyi-kompyuternyie/elementyi-dokazatelnogo-programmirovaniya-54365.html (дата обращения: 02.12.2018).
  9. Порождающее программирование // Structuralist . [2005—2018].URL: http://www.structuralist.narod.ru/dictionary/generativeprogramming.htm (дата обращения: 02.12.2018).
  10. Аспектно-ориентированное программирование // Википедия [2018—2018].URL: https://ru.wikipedia.org/wiki/ (дата обращения: 11.01.2019).
  11. Рекурсия. Тренировочные задачи // Хабр. [2006—2019]. URL: https://habr.com/post/275813/ (дата обращения: 11.01.2019).
  12. Автоматное программирование. [2018—2018].URL: http://bourabai.kz/alg/automat.htm(дата обращения: 11.01.2019).
  13. Событийно-ориентированное программирование // StudFiles . [2018—2018].URL: https://studfiles.net/preview/6831885/page:3/ (дата обращения: 11.01.2019).
  14. Компоненто-ориентированное программирование // Wiki 2 . [2018—2018].URL: https://wiki2.org/ru/Компонентно-ориентированное_программирование (дата обращения: 11.01.2019).
  15. Грамотное программирование // StudFiles . [2015—2018].URL: https://studfiles.net/preview/3873949/page:26/ (дата обращения: 11.01.2019).