Разработчики определили и структурировали подходы к решению задач. Они объединили их в понятные правила и назвали парадигмами. Языки программирования конструируются на основе этих правил. У каждого языка есть свой набор парадигм, которым следуют при разработке.
Ещё парадигмами называют запрет на определённые действия внутри кода программы. Его придумал Роберт Мартин — международный консультант в области разработки, известный среди разработчиков как дядя Боб. С его точки зрения, парадигмы — это ограничения на определённые языковые конструкции, которые вынуждают использовать определённый стиль. Например, процедурное программирование накладывает запрет на прыжки по коду программы, а функциональное — на прямое изменение памяти компьютера.
Парадигмы программирования определяют стандарты написания кода. При переходе на другой язык, отвечающий знакомой парадигме, специалисту будет легче преодолеть «языковой барьер».
Две основные парадигмы, императивная и декларативная, включают в себя другие. Например, к императивной парадигме относится процедурное и объектно-ориентированное программирование (ООП), а к декларативной — функциональное и логическое.
Попробуем приготовить тыквенный суп, используя основные парадигмы программирования.
Императивное программирование развивалось как процедурное, где основное понятие — это функция. Функция, или процедура — это последовательность действий, которые записали и назвали. Например, инструкция по сборке шкафа или рецепт тыквенного супа — это функции. Процедура и функция — одно и то же понятие, но процедурное и функциональное программирование различаются. Первое относится к императивной парадигме, а второе — к декларативной.
В своё время процедурное программирование произвело революцию, вытеснив такой язык, как Assembler, но сейчас оно ушло на покой, уступив место объектно-ориентированному.
В парадигме объектно-ориентированного программирования появляются объекты, которые сами выполняют функции. При таком подходе принято считать, что приготовление супа выполняет некий объект, который создаётся внутри программы. В реальности все действия в компьютере выполняет процессор, но в рамках объектно-ориентированного подхода объекты — это сущности, которые могут сами производить операции.
Объектно-ориентированное программирование позволяет регулировать связи между частями программы, которые отвечают за разные действия. За счёт этого программу легче разделить между разработчиками, проще поддерживать и легче автоматически протестировать.
Георгий Осипов
В программировании очень легко допустить неочевидные ошибки, которые сложно заметить, потому что они не проявляются до поры до времени. Например, у разработчика, тестировщика и клиента всё работает, но в один прекрасный момент в банке при определённой транзакции пропадает миллиард долларов. Будет трудно найти причину. Поэтому в программировании очень важно не только написать программу и убедиться, что она работает, но и тщательно проверить её корректность. Если чётко следовать парадигмам, то у разработчика будет меньше возможностей ошибиться, а значит, и программы, которые он напишет, будут более надёжными.
К современной декларативной парадигме прежде всего относится функциональное программирование. В строгом функциональном подходе считается, что все функции чистые и не имеют побочных эффектов. Гость может заказать хоть тысячу раз тыквенный суп, и каждый раз официант принесёт ему одно и то же блюдо. Результат функции всегда будет одинаковым. Но в реальном ресторане на десятый раз закончились бы сливки 20% и их бы заменили на 10%, на двадцатый — закончилась бы и тыква, а функция стала бы выдавать ошибку «невозможно приготовить тыквенный суп». Это и есть побочный эффект — то, что изменилось в мире при работе функции, о чём пользователь может не знать.
Чтобы решить эту проблему, при функциональном подходе нельзя просто заказать суп, а нужно предъявить все продукты, необходимые для приготовления. То, что от них останется, будет возвращено в качестве результата вместе с самим супом.
В функциональных языках побочных эффектов нет, поэтому нет и понятия изменения объектов. Функция не меняет старый объект, а возвращает новый. Это всё равно что каждый день покупать новый календарь вместо того, чтобы перевернуть лист старого. В большинстве случаев такие напрасные траты может оптимизировать транслятор — приложение, которое будет решать, как именно исполнять код.
Функциональное программирование подходит не для любых задач. С его помощью сложно написать игру в жанре «стратегия в реальном времени». В таких играх юниты, или игровые персонажи, перемещаются по игровому полю. Перемещение одного юнита — это изменение поля, а в строгом функциональном стиле изменения запрещены. Можно только создать полностью новую вселенную с новыми позициями игроков. Эта операция, скорее всего, потребует столько вычислительных ресурсов, что игра будет заметно тормозить. Современные функциональные языки имеют обходные пути для решения подобных задач, но для некоторых алгоритмов их трудно найти, если работать только в рамках функционального стиля.
1. Процедурная парадигма подойдёт для написания кода микрочипа.
Он может иметь слишком специфичный процессор, чтобы разрабатывать для него компилятор сложного объектно-ориентированного языка. Технических возможностей чипа может быть недостаточно для работы программ, написанных на современных языках.
2. Объектно-ориентированная парадигма.
Каждый пользовался программами, написанными с использованием объектно-ориентированной парадигмы. Большинство современных приложений для компьютеров и смартфонов, популярные интернет-сервисы, умный телевизор и роутер написаны на объектно-ориентированном языке.
3. Декларативная парадигма отлично подходит для описания внешнего вида веб-сайтов.
Сейчас для этого используется декларативное программирование на языке CSS (от англ. Cascading Style Sheets — «каскадные таблицы стилей»). С его помощью задают шрифт текста, цвет фона, размер картинки.
4. Функциональная парадигма используется в криптовалютах и блокчейне.
Это области, в которых надёжность выдвигается на первый план, они новые и открыты для экспериментальных технологий. Другие функциональные языки стирают грань между математикой и программированием, позволяя буквально программировать математические доказательства. В основе этого соответствие Карри — Ховарда — математический факт, который гласит, что программа на функциональном языке и доказательство — это одно и то же. Его можно использовать для формальной верификации — строгой автоматической проверки корректности программ.
Почти все парадигмы используются для промышленных программ общего назначения, например, текстовых и графических редакторов, электронных таблиц, приложений на телефон, web-сервисов. Есть и такие, которые применяют в языках, предназначенных для очень специфических задач. Например, логическую парадигму разработчики используют для решения математических уравнений, а язык Prolog поможет решить судоку, потому что решение головоломки можно сформулировать в виде набора ограничений.
Георгий Осипов
Нужно брать из каждой парадигмы лучшее. Например, у функциональной парадигмы поучиться тому, что побочный эффект — это не всегда хорошо, а у императивной — контролю над действиями программы. Можно писать в рамках любой парадигмы, главное — помнить, что результат программы это не только то, что она делает, но и то, как именно написан код.
Смысл не только в том, чтобы программа работала и выдавала красивый результат, но и в том, чтобы она была написана правильно. Если она будет красивой внутри, то другие разработчики её поймут, смогут оценить и дополнить.
Читать также: