Парадигмы программирования: что это такое и на что они влияют
hard

Парадигмы программирования: что это такое и на что они влияют

Мы все ими пользуемся, но не знаем об этом

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

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

Это — теория программирования, со схемами и разборами, практики тут не будет. Если хотите потренироваться в разработке, сделайте игру на Python, в которой нужно уворачиваться от предметов, или потренируйтесь создавать красивый текст с помощью CSS.

Что такое парадигмы программирования

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

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

Здесь есть два главных определения:

  • Парадигма программирования — устоявшаяся система взглядов и подходов, в рамках которых идёт разработка. Это определение сформировал историк и философ Томас Кун.
  • Парадигма — запрет конкретных действий при работе над программой. Автор этого тезиса — инженер и программист Роберт Мартин.

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

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

Мы рассмотрим несколько основных, которые используются сегодня, — и вспомним, как на появление разных парадигм повлияли разные виды программирования.

Императивная парадигма

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

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

  • Компьютер выполняет последовательно записанные команды.
  • Инструкции могут использовать результаты, полученные после выполнения предыдущих команд.
  • Данные могут сохраняться в памяти.
  • Состояние программы может изменяться после каждой инструкции.
  • Основа императивного программирования — операторы присваивания, которые управляют состоянием переменных.

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

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

Как правило, императивное программирование решает небольшие подзадачи для поддержания работы основной программы. Использовать эту парадигму (но не ограничиваться ею) можно почти во всех современных языках: C, C#, C++, Python, Java, Ruby.

Чем больше становились программы, тем труднее было работать с императивной парадигмой, поэтому появились новые.

Декларативная парадигма

Если императивное программирование подразумевает максимально подробные инструкции для машины, то декларативная парадигма работает по-другому: описывает не способ решения, а желаемый результат. Она отвечает на вопрос: «Что делает программа и что должно получиться в итоге?»

Как это выглядит:

  • Компьютер сам выбирает действия для достижения результата.
  • Состояние программы не меняется и не отслеживается в процессе работы.
  • Декларативное программирование не использует переменные и операторы присваивания.

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

  1. Точная адаптация под конкретные задачи. Декларативное программирование создаёт высокоуровневый слой функциональности, который выполняет заранее продуманные инструкции. 
  2. Защита от ошибок. Скрытая реализация не даёт что-то поломать в системе. Например, мы можем неправильно использовать запросы SQL, но не можем испортить сами запросы.

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

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

Звучит удобно, но полностью на компьютер полагаться нельзя. Может получиться что-то вроде такого: мы сказали программе выдавать купоны на скидку на определённые товары после регистрации в сервисе. Товары закончились, а компьютер этого не понимает и продолжает выдавать бесполезные купоны. Клиент регистрируется и получает скидку на то, что купить всё равно уже не может. В итоге злится, расстраивается, теряет доверие.

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

Сравнение императивной и декларативной парадигм

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

Синтаксис и структура кода. Декларативные языки программирования чаще всего высокоуровневые, легкочитаемые и выразительные. С их помощью можно кратко и лаконично описать, чего мы ожидаем от работы программы. Примеры декларативных языков — SQL и HTML.

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

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

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

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

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

Порядок выполнения команд. После запуска программа следует определённому алгоритму и списку инструкций. 

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

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

В императивной парадигме мы пишем, КАК что-то должно быть сделано, а в декларативной — ЧТО нам нужно в итоге, чтобы программа сделала

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

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

Модульная парадигма

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

Модули часто выносятся в отдельные файлы и папки, которые лежат вместе с основным проектом. Ещё при импорте библиотек в проекте часто нужна не вся библиотека, а только её часть — это тоже будет один из модулей.

Процедурная парадигма

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

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

Логика такая: мы пишем много функций, каждая из которых делает что-то своё, а потом объединяем их в коде для решения задачи.

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

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

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

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

Структурная парадигма

Структурная парадигма делит код на модули и подразумевает управление ими через три основных принципа — структуры управления:

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

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

Императивная парадигма сам по себе не запрещала использование оператора goto, а структурная — запретила. Код стал более надёжным и легкочитаемым.

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

Логическая парадигма

Это продолжение декларативной парадигмы, поэтому при логическом программировании мы описываем, что нужно получить, и стараемся дать подходящие входные данные.

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

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

Функциональная парадигма

Это процедурное программирование, но на декларативный лад.

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

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

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

Что учить сначала

Одни парадигмы не хуже других, нет смысла изучать какие-то определённые. 

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

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

Обложка:

Алексей Сухов

Корректор:

Ирина Михеева

Вёрстка:

Мария Климентьева

Соцсети:

Юлия Зубарева

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Вам может быть интересно
hard
[anycomment]
Exit mobile version