Парадигма программирования 4 Императивное программирование 6



Скачать 43,03 Kb.
страница1/5
Дата02.08.2022
Размер43,03 Kb.
#187953
  1   2   3   4   5
Связанные:
Microsoft Word Document
Системная архитектура и структура ORACLE

Оглавление
Введение 3
Парадигма программирования 4
Императивное программирование 6
Параллельное и событийно-управляемое программирование 8
Объектно-ориентированное программирование 11
Функциональное программирование 14
Логическое программирование 18
Программирование в ограничениях 22
Заключение 25
Список использованных источников 26
Введение
Поскольку деятельность любого субъекта в значительной степени зависит от степени владения информации, а также способности эффективно ее использовать. Для свободной ориентации в информационных потоках современный специалист должен уметь получать, обрабатывать и использовать информацию, прежде всего, с помощью компьютеров, а также телекоммуникаций и других новейших средств связи, в том числе и уметь, обращаться с языками программирования. 
Актуальность данной темы обусловлена тем, что прогресс компьютерных технологий определил процесс появления новых разнообразных знаковых систем для записи алгоритмов – языков программирования. 
Связь между языком, на котором мы думаем, программируем, и задачами и решениями, которые мы можем представлять в своем воображении, очень близка. Язык предоставляет программисту набор концептуальных инструментов, если они не отвечают задаче, то их просто игнорируют. Хорошее проектирование и отсутствие ошибок не может гарантироваться чисто за счет языковых средств. Сегодня практически все программы создаются с помощью языков программирования. Неотъемлемая часть современных ЭВМ – системы программного обеспечения, являющиеся продолжением логических средств ЭВМ, расширяющим возможности аппаратуры и сферу их использования. Основное назначение программного обеспечения – повышение эффективности труда пользователя, а также увеличение пропускной способности ЭВМ посредством сокращения времени и затрат на подготовку и выполнение программ.
Парадигма программирования
Своим современным значением в научно-технической области термин «парадигма» обязан, по-видимому, Томасу Куну и его книге «Структура научных революций» Кун называл парадигмами устоявшиеся системы научных взглядов, в рамках которых ведутся исследования. Согласно Куну, в процессе развития научной дисциплины может произойти замена одной парадигмы на другую (как, например, геоцентрическая небесная механика Птолемея сменилась гелиоцентрической системой Коперника), при этом старая парадигма ещё продолжает некоторое время существовать и даже развиваться благодаря тому, что многие её сторонники оказываются по тем или иным причинам неспособны перестроиться для работы в другой парадигме.
Термин «парадигма программирования» впервые применил Роберт Флойд в своей лекции лауреата премии Тьюринга.
Паради́гма программи́рования – это совокупность идей и понятий, определяющих стиль написания программ. Парадигма в первую очередь определяется базовой программной единицей и самим принципом достижения модульности программы. В качестве этой единицы выступают определение (декларативное, функциональное программирование), действие (императивное программирование), правило (продукционное программирование), диаграмма переходов (автоматное программирование) и др. сущности. В современной индустрии программирования очень часто парадигма программирования определяется набором инструментов программиста, а именно, языком программирования и используемыми библиотеками.
Парадигма программирования определяет то, в каких терминах программист описывает логику программы. Например, в императивном программировании программа описывается как последовательность действий, а в функциональном программировании представляется в виде выражения и множества определений функций (слово определение (англ. definition) следует понимать в математическом смысле). В популярном объектно-ориентированном программировании (в дальнейшем ООП) программу принято рассматривать как набор взаимодействующих объектов. ООП, в основном, есть по сути императивное программирование, дополненное принципом инкапсуляции данных и методов в объект (принцип модульности) и наследованием (принципом повторного использования разработанного функционала). Важно отметить, что парадигма программирования не определяется однозначно языком программирования – многие современные языки программирования являются мультипарадигменными, то есть допускают использование различных парадигм. Так на языке Си, который не является объектно-ориентированным, можно писать объектно-ориентированным образом, а на Ruby, в основу которого в значительной степени положена объектно-ориентированная парадигма, можно писать согласно стилю функционального программирования.
Императивное программирование
Императивное программирование - автомат, последовательно изменяющий свои состояния под управлением некоторой схемы, наиболее просто реализуется технически. Поэтому первые компьютеры были императивными. И остались такими и в наши дни, несмотря на все эксперименты с оригинальными вычислительными устройствами. Даже типичное определение алгоритма, несет на себе сильнейший отпечаток императивного подхода.
Одна из характерных черт императивного программирования - наличие переменных с операцией "разрушающего присвоения". То есть, была переменная А, было у нее значение Х. Алгоритм предписывает на очередном шаге присвоить переменной А значение Y. То значение, которое было у А, будет "навсегда забыто". Вот что на практике означает "переход между состояниями под управлением функции переходов".
Синтаксис описания алгоритмов в простейшем языке, поддерживающем императивную модель программирования, мог бы быть таким:
Оператор ::= Простой оператор | Структурный оператор 
Простой оператор ::= Оператор присваивания | Оператор вызова | Оператор возврата 
Структурный оператор ::= Оператор последовательного исполнения | Оператор ветвления | Оператор цикла 
Оператор присванивания ::= Переменная := Выражение ; 
Оператор вызова ::= Имя подпрограммы ( Список параметров ) ; 
Оператор возврата ::= return [ Выражение ] ; 
Оператор последовательного исполнения ::= begin Оператор* end 
Оператор ветвления ::= if Выражение then Оператор* (elseif Выражение then Оператор*)* [ else Оператор* ] end 
Оператор цикла ::= while Выражение do Оператор* end
Семантика такого языка описывается достаточно легко. Состоянием вычислительного устройства будут указатель текущей инструкции, значения всех используемых программой ячеек памяти, и состояние стека возвратов из подпрограмм. Исполнение каждого оператора тривиальным образом записывается как изменение этого "состояния вычислителя" (если считать, что алгоритм представлен в виде дерева вывода в указанной грамматике, то с описанием переходов не должно возникнуть никаких проблем).
Про наш мир можно сказать, что он локально императивен. То есть, если взять достаточно узкую задачу, то ее можно вполне легко описать методами последовательного программирования. Практика показывает, что более сложные императивные программы (компиляторы, например) пишутся и отлаживаются долго (годами). Переиспользование кода и создание предметно-ориентированных библиотек упрощает программирование, но ошибки в реализации сложных алгоритмов проявляются очень часто.
Императивное программирование наиболее пригодно для реализации небольших подзадач, где очень важна скорость исполнения на современных компьютерах. Кроме этого, работа с внешними устройствами, как правило, описывается в терминах последовательного исполнения операций, что делает такие задачи идеальными кандидатами на императивную реализацию.
Параллельное и событийно-управляемое программирование
Исторически сложилась такая ситуация, что компьютеры изначально использовались для решения больших вычислительных задач, которые были просто "неподъемны" для человека. Для таких задач характерно, что приходится проделывать практически те же вычисления для каждого элемента очень большого массива данных. Постепенно многие крупные организации осознали пользу компьютеров как средств централизованного хранения и обработки своих "картотек" (из которых и выросли современные базы данных). Оказалось, что и в задачах, связанных с систематизацией такой информации, оказывается много общего с численными методами математической физики, в терминах алгоритмической реализации. Достаточно быстро были разработаны супер-ЭВМ, имеющие "векторную" или "матричную" архитектуру. Такие ЭВМ представляют, на самом деле, несколько процессоров, достаточно автономных, но способных обмениваться между собой информацией о результатах своих вычислений. Достаточно хорошим приближением к таким архитектурам являются сети компьютеров с возможностью распределенных вычислений. Кроме этого, практически все современные микропроцессоры максимально используют в своей архитектуре возможности параллельного исполнения отдельных операций. Таким образом, параллелизм можно мысленно разбить на два уровня: параллелизм уровня микроопераций и параллелизм уровня процессов.
Процессы - это абстракция достаточно высокого уровня. В какой вычислительной модели работает каждый отдельный процесс - не принципиально. Важно, что они могут работать параллельно, и могут обмениваться между собой результатами своих вычислений через "каналы связи". Примерно такую модель взаимодействия процессов реализует язык параллельного программирования Occam.
Вот некоторая грамматика описания процессов, достаточно близкая к принятой в Occam-е:
Процесс ::= Простой процесс | Структурный процесс 
Простой процесс ::= Послать значение | Принять значение | Процесс вычислительной модели 
Структурный процесс ::= Последовательный процесс | Параллельный процесс 
Послать значение ::= Канал связи << Выражение ; 
Принять значение ::= Канал связи >> Выражение ; 
Процесс вычислительной модели ::= нечто, определяемое конкретным вычислителем 
Последовательный процесс ::= seq Процесс* end 
Параллельный поцесс ::= par Процесс* end
Семантически взаимодействие параллельных процессов лучше всего представлять как работу сети неких устройств, соединенных "проводками", по которым текут данные. Спроектировав в таких терминах, например, систему параллельных процессов для быстрого суммирования большого количества чисел, можно легко описать эту систему в приведенном синтаксисе. Каждый вычислитель производит типичные для его вычислительной модели операции (например, императивный вычислитель будет переходить из состояния в состояние). Когда процесс встречает инструкцию "Принять значение (из канала)", он входит в состояние ожидания, пока канал пуст. Как только в канале появляется значение, процесс его считывает и продолжает работу.
Достаточно распространенной является так же и следующее понимание параллелизма: в системе параллельных процессов каждый отдельный процесс обрабатывает события. События могут быть как общими для всей системы, так и индивидуальными для одного или нескольких процессов. В таких терминах достаточно удобно описывать, например, элементы графического интерфейса пользователя, или моделирование каких-либо реальных процессов (например, управление уличным движением) - так как понятие события является для таких задач естественным. Такое программирование принято называть событийно-управляемым. В событийно-управляемом программировании отдельные процессы максимально автономны, единственное средство общения между ними - посылка сообщений (порождение новых событий). Событийно-управляемое программирование очень близко к объектно-ориентированному программированию, которое будет подробно разобрано в дальнейшем. Параллелизм является не только надстройкой над другими вычислительными моделями; некоторые методологии программирования имеют естественную реализацию на платформах, поддерживающих параллелизм.
Объектно-ориентированное программирование
Объектно-ориентированное программирование появилось из событийно-управляемого программирования и практически затмило его своим светом, так как оказалось значительно более мощным и универсальным средством программирования и проектирования. В чистом объектно-ориентированном программировании все, что можно - процессы, данные, события - являются объектами. Все объекты располагают некоторыми собственными данными, представленными как ссылки на другие объекты. Объекты могут обмениваться между собой сообщениями. При получении объектом сообщения запускается соответствующий ему обработчик, иначе называемый методом. У объекта есть ассоциативный контейнер, который позволяет получить по сообщению его метод для его обработки. Кроме этого, у объекта есть объект-предок. Если метод для обработки сообщения не найден, сообщение будет перенаправлено объекту-предку. Эту структуру в целом (таблица обработчиков + предки) из соображений эффективности выделяют в отдельный объект, называемый классом данного объекта. У самого объекта будет ссылка на объект, представляющий его класс. Объект по отношению к своему классу является экземпляром. Так как классы тоже представлены, как объекты, существует класс, определяющий поведение, общее для всех классов. Такой класс принято называть метаклассом.
Важно выделить следующие основные свойства объектов:
1.) Так как один объект может воздействовать на другой исключительно при помощи посылки последнему сообщений, он не может как-либо непосредственно работать с собственными данными "собеседника", и, следовательно, не может нарушить их внутреннюю согласованность. Это свойство (сокрытие данных) принято называть инкапсуляцией.
2.) Так как объекты взаимодействуют исключительно за счет обмена сообщениями, объекты-собеседники могут ничего не знать о реализации обработчиков сообщений у своего визави. Взаимодействие происходит исключительно в терминах сообщений/событий, которые достаточно легко привязать к предметной области. Это свойство (описание взаимодействия исключительно в терминах предметной области) называют абстракцией.
3.) Объекты взаимодействуют исключительно через посылку сообщений друг другу. Поэтому если в каком-либо сценарии взаимодействия объектов заменить произвольный объект другим, способным обрабатывать те же сообщения, сценарий так же будет реализуем. Это свойство (возможность подмены объекта другим объектом со сходной структурой класса) называется полиморфизмом.
Отношение "потомок-предок" на классах принято называть наследованием.
Все эти свойства по отдельности встречаются и в других методологиях программирования. Так, локальные переменные инкапсулированы в процедуре. Объектно-ориентированное программирование достаточно гармонично их сочетает.
Синтаксис чистых объектно-ориентированных языков описывает всего одну операцию: послать сообщение M объекту А с параметрами B1..Вn. Параметры сообщения - это объекты, которые сами могут быть результатами обработки других сообщений. Часто операцию "вернуть объект-результат" так же вводят в явном виде, хотя ее достаточно легко реализовать как посылку сообщения системному объекту "стек возвращаемых значений".
Если в чистом объектно-ориентированном языке нужно создать новый класс - требуется послать классу-предку сообщение: "породить наследника" ( sublcass ). Существует класс, являющийся вершиной всей иерархии наследования (как правило, называемый Object), так что предок будет у всех классов, даже явно его не имеющих. Для описания обработки сообщения нужно послать классу, в котором задается обработчик, сообщение: "установить новый обработчик сообщения" ( answer ).
Пример описания класса "точка" в некотором абстрактном объектно-ориентированном языке (напоминающем SmallTalk или Common LISP Object System = CLOS):
Object <- subclass(Point, (X, Y)), 
Point <- answer( isnew, (Init_X, Init_Y), 
( Integer <- new(X, Init_X), 
Integer <- new(Y, Init_Y) 
)), 
Point <- answer( move, (Delta_X, Delta_Y), 
( X <- add(Delta_X), 
Y <- add(Delta_Y)
)) 
...
Если мы в дальнейшем хотим использовать класс Point, например, порождая его объекты и как-то с ними работая, мы можем написать нечто вроде:
Point <- new(A, (0, 0)), 
A <- move(+2, -2) 
...
В наши дни объектно-ориентированное программирование активно используется как средство проектирования сложных систем и моделирования, например, в языке UML.

Скачать 43,03 Kb.

Поделитесь с Вашими друзьями:
  1   2   3   4   5




База данных защищена авторским правом ©psihdocs.ru 2022
обратиться к администрации

    Главная страница