Перейти к содержанию

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

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

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

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

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

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

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

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

  • Обеспечение качества: Парадигмы программирования способствуют соблюдению стандартов и лучших практик, что повышает качество программного обеспечения и облегчает его поддержку.

Цели введения парадигм программирования:

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

Место парадигмы в разработке#

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

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

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

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

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

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

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

https://ratcatcher.ru/media/inf/pr/pr4/image.png

Общая схема классификации языков программирования#

https://ratcatcher.ru/media/inf/pr/pr4/image_2.png

Императивные языки программирования#

Определения

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

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

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

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

Состояние программы (англ. program state) совокупность данных, связанных со всеми используемыми программой переменными в конкретный момент времени.

Классическими примерами императивных языков программирования являются C++, Java. Они широко используются для разработки разнообразных прикладных и системных программ, так как предоставляют контроль над аппаратными ресурсами и оптимизацию выполнения задач. Однако, программы на императивных языках могут быть более сложными в сопровождении и расширении по сравнению с программами, написанными на более декларативных или функциональных языках.

Основные характеристики императивных языков программирования:

  • Состояние и изменение состояния: Императивные языки позволяют программистам описывать изменения состояния программы, такие как изменение значений переменных или структур данных. Это делается с помощью команд и инструкций, которые модифицируют текущее состояние программы.

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

  • Управление потоком: Императивные языки предоставляют средства для управления потоком выполнения программы, такие как условные операторы (if-else), циклы (for, while) и переходы (break, continue, return).

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

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

Определения

Структурное программирование (англ. structured programming) - парадигма, в основе которой лежит представление программы в виде иерархии блоков.

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

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

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

https://ratcatcher.ru/media/inf/pr/pr4/image_3.png

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

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

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

Концепции:

▶ выделение повторяющегося кода в подпрограммы (процедуры и функции);
▶ объединение логически связанных подпрограмм в модули;
▶ использование блоков инструкций для контроля области видимости переменных и функций;
▶ проектирование программ сверху вниз;
▶ разделение интерфейсов и имплементаций подпрограмм в модулях.

Языки программирования: Algol, C, Pascal, Ada, FORTRAN, PL/I.

Теорема о структурированной программе (Бём, Якопини)#

Теорема Бёма — Якопини — положение структурного программирования, согласно которому любой исполняемый алгоритм может быть преобразован к структурированному виду, то есть такому виду, когда ход его выполнения определяется только при помощи трёх структур управления: последовательной (англ. sequence), ветвлений (англ. selection) и повторов или циклов (англ. iteration).

Эта теорема была представлена независимо Коррадо Бёмом в 1968 году и Николой Якопини в 1966 году. Теорема утверждает, что любая произвольная программу можно представить в виде структурированной программы, состоящей из следующих базовых структур:

  1. Последовательность (sequence): Это упорядоченная последовательность инструкций, которые выполняются одна за другой. Важно отметить, что в этой структуре нет переходов или ветвлений.

  2. Условное ветвление (conditional): Эта структура включает в себя условный оператор (if-else), который позволяет выбирать, какой блок инструкций выполнить в зависимости от определенного условия.

  3. Цикл (loop): Эта структура включает в себя цикл (например, while или for), который позволяет многократно выполнять определенный блок инструкций, пока выполняется некоторое условие.

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

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

Определения

Объектно-ориентированное программирование (англ. object-oriented programming) - парадигма, согласно которой программа представляется в виде взаимодействующих объектов.

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

Объект сильная связь между структурами данных и методами (≃ функциями), обрабатывающими эти данные. Составляющие объекта:
▶ идентификатор;
▶ свойства;
▶ методы.

Особенность: развитие структурного программирования с объединением в объектах данных и поведения.

Концепции:

  • Объекты: Объекты являются основными строительными блоками ООП. Они представляют конкретные сущности из реального мира, имеют свойства (атрибуты) и могут выполнять действия (методы). Например, объект "автомобиль" может иметь атрибуты, такие как "марка" и "скорость", и методы, такие как "завести" и "остановить".

  • Классы: Классы служат шаблонами или описаниями для создания объектов. Класс определяет атрибуты и методы, которые будут у объектов этого класса. Например, класс "автомобиль" определяет атрибуты "марка" и "скорость", а также методы "завести" и "остановить".

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

  • Наследование: Наследование позволяет создавать новые классы на основе существующих классов. Класс-наследник наследует атрибуты и методы родительского класса и может добавлять к ним новые или переопределять существующие. Это позволяет создавать иерархии классов и повторно использовать код.

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

  • Абстракция: Абстракция представляет собой процесс выделения существенных характеристик объекта и игнорирования ненужных деталей. Она помогает создавать упрощенные модели реального мира для программирования.

https://ratcatcher.ru/media/inf/pr/pr4/image_4.jpg

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

Определения

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

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

https://ratcatcher.ru/media/inf/pr/pr4/image_6.png

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

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

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

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

Примерами декларативных языков программирования являются SQL (Structured Query Language) для работы с базами данных, HTML/CSS для описания структуры и стиля веб-страниц, а также языки для описания логики бизнес-правил, такие как Datalog или Prolog.

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

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

  • Отсутствие явного управления потоком: Вместо явного определения последовательности операций и контроля над потоком выполнения, декларативный код описывает отношения между данными и действиями. Это позволяет сконцентрироваться на "чем" делать, а не "как" делать.

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

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

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

Определения

** Логическое программирование ** (англ. logic programming) - парадигма, согласно которой программа представляет собой вывод с помощью правил формальной логики.

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

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

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

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

https://ratcatcher.ru/media/inf/pr/pr4/image_5.png

Концепции:
▶ процедурная интерпретация правил:
H :− B1, . . . , Bn;
чтобы вычислить H, нужно вычислить B1, …, Bn.
▶ контроль над стратегией доказательства утверждений (параллельный или последовательный поиск, перебор с возвратом, …).

Языки программирования: Prolog и диалекты, Oz.

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

Определения

Функциональное программирование (англ. functional programming) - парадигма, согласно которой процесс исполнения программы представляется последовательностью вычислений значений для математических функций.

Основными концепциями и характеристиками функционального программирования являются:

  • Чистые функции: Чистая функция - это функция, которая всегда возвращает одинаковый результат для одинаковых входных данных и не имеет побочных эффектов, то есть она не изменяет состояние программы и не взаимодействует с внешними данными. Чистые функции обеспечивают предсказуемость и облегчают отладку.
  • Неизменяемость данных: Функциональное программирование обычно поддерживает неизменяемость данных, что означает, что данные после создания не могут быть изменены. Вместо этого создаются новые данные на основе старых. Это способствует предотвращению ошибок и облегчает параллельное выполнение кода.
  • Рекурсия: Рекурсия является естественной и часто используемой конструкцией в функциональном программировании. Функции могут вызывать сами себя для решения задач, что особенно полезно для обработки списков и структур данных.
  • Высшие порядки функций: Функциональное программирование поддерживает высшие порядки функций, что означает, что функции могут принимать другие функции в качестве аргументов или возвращать их. Это позволяет выразительно описывать операции над функциями и обобщать паттерны.
  • Функции высших порядков: Этот прием позволяет абстрагировать общие операции в функциях и использовать их для множества различных типов данных. Это способствует созданию более компактного и универсального кода.
  • Ленивые вычисления: В функциональном программировании можно использовать ленивые вычисления, при которых вычисления выполняются только в тот момент, когда результат действительно требуется. Это может повысить производительность и уменьшить потребление ресурсов.

https://ratcatcher.ru/media/inf/pr/pr4/image_4.jpg

Парадигмы программирования и Языки программирования (ЯП)#

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

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

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

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

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

Важно отметить, что некоторые языки программирования позволяют смешивать различные парадигмы программирования в рамках одного проекта. Это дает разработчикам гибкость и возможность выбора наилучшего подхода для каждой конкретной ситуации. Например, язык C++ поддерживает как объектно-ориентированное программирование (ООП), так и процедурное программирование, что позволяет разрабатывать разнообразные приложения.

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

https://ratcatcher.ru/media/inf/pr/pr4/image_7.png

Примеры для сравнения Парадигм#

Задача 1
У человека X и человека Y есть ОДИНАКОВЫЙ_ВОЗРАСТ, когда человек X имеет возраст A и человек Y имеет возраст A.
Далее людям задаются определённые возраста.

https://ratcatcher.ru/media/inf/pr/pr4/image_8.png

Задача 2
Вычислите факториал числа Х
https://ratcatcher.ru/media/inf/pr/pr4/image_9.png

Используемая литература#

  1. Парадигма программирования : курс лекций / Л. В. Городняя ; Новосиб. гос. ун-т. – Новосибирск : РИЦ НГУ, 2015. – 206 с.
  2. Теория и практика языков программирования: Учебник для вузов. Стандарт 3-го поколения. — СПб.: Питер, 2013. — 688 с.: ил.