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

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

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

Идеологически ООП - подход к программированию как к моделированию информационных объектов, решающий на новом уровне основную задачу структурного программирования : структурирование информации с точки зрения управляемости , что существенно улучшает управляемость самим процессом моделирования, что в свою очередь особенно важно при реализации крупных проектов. Управляемость для иерархических систем предполагает минимизацию избыточности данных (аналогичную нормализации) и их целостность, поэтому созданное удобно управляемым - будет и удобно пониматься. Таким образом через тактическую задачу управляемости решается стратегическая задача - транслировать понимание задачи программистом в наиболее удобную для дальнейшего использования форму.
Основные принципы структурирования в случае ООП связаны с различными аспектами базового понимания предметной задачи, которое требуется для оптимального управления соответствующей моделью:
- абстрагирование для выделения в моделируемом предмете важного для решения конкретной задачи по предмету, в конечном счете - контекстное понимание предмета, формализуемое в виде класса;
- инкапсуляция для быстрой и безопасной организации собственно иерархической управляемости: чтобы было достаточно простой команды «что делать», без одновременного уточнения как именно делать, так как это уже другой уровень управления;
- наследование для быстрой и безопасной организации родственных понятий: чтобы было достаточно на каждом иерархическом шаге учитывать только изменения, не дублируя все остальное, учтенное на предыдущих шагах;
- полиморфизм для определения точки, в которой единое управление лучше распараллелить или наоборот - собрать воедино.
То есть фактически речь идет о прогрессирующей организации информации согласно первичным семантическим критериям: «важное/неважное», «ключевое/подробности», «родительское/дочернее», «единое/множественное». Прогрессирование, в частности, на последнем этапе дает возможность перехода на следующий уровень детализации, что замыкает общий процесс.
Обычный человеческий язык в целом отражает идеологию ООП, начиная с инкапсуляции представления о предмете в виде его имени и заканчивая полиморфизмом использования слова в переносном смысле, что в итоге развивает выражение представления через имя предмета до полноценного понятия-класса.

Энциклопедичный YouTube

    1 / 5

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

    ✪ Объектно-ориентированное проектирование, часть 1 - как проектируются классы

    ✪ Основные принципы объектно-ориентированного программирования. Что такое ООП и зачем оно нужно?

    ✪ Основы ООП в C++

    ✪ Объектно-ориентированное программирование. Классы и объекты. Урок 3

    Субтитры

Основные понятия

Абстракция данных Абстрагирование означает выделение значимой информации и исключение из рассмотрения незначимой. В ООП рассматривают лишь абстракцию данных (нередко называя её просто «абстракцией»), подразумевая набор значимых характеристик объекта, доступный остальной программе. Инкапсуляция Инкапсуляция - свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе. Одни языки (например, С++ , Java или Ruby) отождествляют инкапсуляцию с сокрытием , но другие (Smalltalk , Eiffel , OCaml) различают эти понятия. Наследование Наследование - свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс - потомком, наследником, дочерним или производным классом. Полиморфизм подтипов Полиморфизм подтипов (в ООП называемый просто «полиморфизмом») - свойство системы, позволяющее использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта. Другой вид полиморфизма - параметрический - в ООП называют обобщённым программированием . Класс Класс - универсальный, комплексный тип данных , состоящий из тематически единого набора «полей» (переменных более элементарных типов) и «методов» (функций для работы с этими полями), то есть он является моделью информационной сущности с внутренним и внешним интерфейсами для оперирования своим содержимым (значениями полей). В частности, в классах широко используются специальные блоки из одного или чаще двух спаренных методов, отвечающих за элементарные операции с определенным полем (интерфейс присваивания и считывания значения), которые имитируют непосредственный доступ к полю. Эти блоки называются «свойствами» и почти совпадают по конкретному имени со своим полем (например, имя поля может начинаться со строчной, а имя свойства - с заглавной буквы). Другим проявлением интерфейсной природы класса является то, что при копировании соответствующей переменной через присваивание, копируется только интерфейс, но не сами данные, то есть класс - ссылочный тип данных. Переменная-объект, относящаяся к заданному классом типу, называется экземпляром этого класса. При этом в некоторых исполняющих системах класс также может представляться некоторым объектом при выполнении программы посредством динамической идентификации типа данных . Обычно классы разрабатывают таким образом, чтобы обеспечить отвечающие природе объекта и решаемой задаче целостность данных объекта, а также удобный и простой интерфейс. В свою очередь, целостность предметной области объектов и их интерфейсов, а также удобство их проектирования, обеспечивается наследованием. Объект Сущность в адресном пространстве вычислительной системы, появляющаяся при создании экземпляра класса (например, после запуска результатов компиляции и связывания исходного кода на выполнение).

Классификация подвидов ООП

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

Наиболее заметные отличия в проявлении показателей качества между языками разных видов:

  • В мейнстримных языках декларируемые принципы нацелены на повышение изначально низкого для императивного программирования коэффициента повторного использования кода . В полиморфно типизированных применение концепций ООП, напротив, означает очевидное его снижение из-за перехода от параметрического полиморфизма к ad hoc полиморфизму . В динамически типизированных языках (Smalltalk , Python , Ruby) эти принципы используются для логической организации программы, и их влияние на коэффициент повторного использования трудно спрогнозировать - он сильно зависит от дисциплины программиста. Например, в CLOS мультиметоды одновременно являются функциями первого класса , что позволяет рассматривать их одновременно и как связанно квантифицированные , и как обобщённые (истинно полиморфные).
  • Традиционные ОО-языки используют номинативную типизацию , то есть допустимость соиспользования объектов разных классов только при условии явного указания родственных отношений между классами. Для полиморфно типизированных языков характерна структурная типизация , то есть согласование классов между собой тем же механизмом, что и согласование числа 5 с типом int . Динамически типизированные языки также занимают здесь промежуточную позицию.

Обобщённое обоснование динамической диспетчеризации (включая множественную) в середине 1990-х годов построил Джузеппе Кастанья .

История

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

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

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

Первым языком программирования, в котором были предложены основные понятия, впоследствии сложившиеся в парадигму, была Симула , но термин «объектная ориентированность» не использовался в контексте использования этого языка. В момент его появления в 1967 году в нём были предложены революционные идеи: объекты, классы, виртуальные методы и др., однако это всё не было воспринято современниками как нечто грандиозное. Фактически, Симула была «Алголом с классами», упрощающим выражение в процедурном программировании многих сложных концепций. Понятие класса в Симуле может быть полностью определено через композицию конструкций Алгола (то есть класс в Симуле - это нечто сложное, описываемое посредством примитивов).

Взгляд на программирование «под новым углом» (отличным от процедурного) предложили Алан Кэй и Дэн Ингаллс в языке Smalltalk . Здесь понятие класса стало основообразующей идеей для всех остальных конструкций языка (то есть класс в Смолтоке является примитивом, посредством которого описаны более сложные конструкции). Именно он стал первым широко распространённым объектно-ориентированным языком программирования .

В настоящее время количество прикладных языков программирования (список языков), реализующих объектно-ориентированную парадигму, является наибольшим по отношению к другим парадигмам. Наиболее распространённые в промышленности языки (С++, Delphi, C#, Java и др.) воплощают объектную модель Симулы. Примерами языков, опирающихся на модель Смолтока, являются Objective-C, Python, Ruby.

Определение ООП и его основные концепции

В центре ООП находится понятие объекта. Объект - это сущность, которой можно посылать сообщения и которая может на них реагировать, используя свои данные. Объект - это экземпляр класса. Данные объекта скрыты от остальной программы. Сокрытие данных называется инкапсуляцией .

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

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

Сложности определения

ООП имеет уже более чем сорокалетнюю историю, но, несмотря на это, до сих пор не существует чёткого общепринятого определения данной технологии . Основные принципы, заложенные в первые объектные языки и системы, подверглись существенному изменению (или искажению) и дополнению при многочисленных реализациях последующего времени. Кроме того, примерно с середины 1980-х годов термин «объектно-ориентированный» стал модным , в результате с ним произошло то же самое, что несколько раньше с термином «структурный» (ставшим модным после распространения технологии структурного программирования) - его стали искусственно «прикреплять» к любым новым разработкам, чтобы обеспечить им привлекательность. Бьёрн Страуструп в 1988 году писал, что обоснование «объектной ориентированности» чего-либо, в большинстве случаев, сводится к ложному силлогизму : «X - это хорошо. Объектная ориентированность - это хорошо. Следовательно , X является объектно-ориентированным».

Роджер Кинг аргументированно настаивал, что его кот является объектно-ориентированным. Кроме прочих своих достоинств, кот демонстрирует характерное поведение, реагирует на сообщения, наделён унаследованными реакциями и управляет своим, вполне независимым, внутренним состоянием.

Однако общность механизма обмена сообщениями имеет и другую сторону - «полноценная» передача сообщений требует дополнительных накладных расходов, что не всегда приемлемо. Поэтому во многих современных объектно-ориентированных языках программирования используется концепция «отправка сообщения как вызов метода» - объекты имеют доступные извне методы, вызовами которых и обеспечивается взаимодействие объектов. Данный подход реализован в огромном количестве языков программирования, в том числе C++ , Object Pascal , Java , Oberon-2 . Однако, это приводит к тому, что сообщения уже не являются самостоятельными объектами, и, как следствие, не имеют атрибутов, что сужает возможности программирования. Некоторые языки используют гибридное представление, демонстрируя преимущества одновременно обоих подходов - например, CLOS , Python .

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

Особенности реализации

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

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

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

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

Инкапсуляция обеспечивается следующими средствами:

Контроль доступа Поскольку методы класса могут быть как чисто внутренними, обеспечивающими логику функционирования объекта, так и внешними, с помощью которых взаимодействуют объекты, необходимо обеспечить скрытость первых при доступности извне вторых. Для этого в языки вводятся специальные синтаксические конструкции, явно задающие область видимости каждого члена класса. Традиционно это модификаторы public, protected и private, обозначающие, соответственно, открытые члены класса, члены класса, доступные внутри класса и из классов-потомков, и скрытые, доступные только внутри класса. Конкретная номенклатура модификаторов и их точный смысл различаются в разных языках. Методы доступа Поля класса в общем случае не должны быть доступны извне, поскольку такой доступ позволил бы произвольным образом менять внутреннее состояние объектов. Поэтому поля обычно объявляются скрытыми (либо язык в принципе не позволяет обращаться к полям класса извне), а для доступа к находящимся в полях данным используются специальные методы, называемые методами доступа. Такие методы либо возвращают значение того или иного поля, либо производят запись в это поле нового значения. При записи метод доступа может проконтролировать допустимость записываемого значения и, при необходимости, произвести другие манипуляции с данными объекта, чтобы они остались корректными (внутренне согласованными). Методы доступа называют ещё аксессорами (от англ. access - доступ), а по отдельности - геттерами (англ. get - чтение) и сеттерами (англ. set - запись) . Свойства объекта Псевдополя, доступные для чтения и/или записи. Свойства внешне выглядят как поля и используются аналогично доступным полям (с некоторыми исключениями), однако фактически при обращении к ним происходит вызов методов доступа. Таким образом, свойства можно рассматривать как «умные» поля данных, сопровождающие доступ к внутренним данным объекта какими-либо дополнительными действиями (например, когда изменение координаты объекта сопровождается его перерисовкой на новом месте). Свойства, по сути, не более чем синтаксический сахар , поскольку никаких новых возможностей они не добавляют, а лишь скрывают вызов методов доступа. Конкретная языковая реализация свойств может быть разной. Например, в объявление свойства непосредственно содержит код методов доступа, который вызывается только при работе со свойствами, то есть не требует отдельных методов доступа, доступных для непосредственного вызова. В Delphi объявление свойства содержит лишь имена методов доступа, которые должны вызываться при обращении к полю. Сами методы доступа представляют собой обычные методы с некоторыми дополнительными требованиями к сигнатуре .

Полиморфизм реализуется путём введения в язык правил, согласно которым переменной типа «класс» может быть присвоен объект любого класса-потомка её класса.

Проектирование программ в целом

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

Объектно-ориентированное проектирование ориентируется на описание структуры проектируемой системы (приоритетно по отношению к описанию её поведения, в отличие от функционального программирования), то есть, фактически, в ответе на два основных вопроса:

  • Из каких частей состоит система ;
  • В чём состоит ответственность каждой из ее частей .

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

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

Большое значение имеет правильное построение иерархии классов. Одна из известных проблем больших систем, построенных по ООП-технологии - так называемая проблема хрупкости базового класса . Она состоит в том, что на поздних этапах разработки, когда иерархия классов построена и на её основе разработано большое количество кода, оказывается трудно или даже невозможно внести какие-либо изменения в код базовых классов иерархии (от которых порождены все или многие работающие в системе классы). Даже если вносимые изменения не затронут интерфейс базового класса, изменение его поведения может непредсказуемым образом отразиться на классах-потомках. В случае крупной системы разработчик базового класса просто не в состоянии предугадать последствия изменений, он даже не знает о том, как именно базовый класс используется и от каких особенностей его поведения зависит корректность работы классов-потомков.

Различные ООП-методологии

Компонентное программирование - следующий этап развития ООП; прототип- и класс-ориентированное программирование - разные подходы к созданию программы, которые могут комбинироваться, имеющие свои преимущества и недостатки.

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

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

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

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

  • Прототип - это объект-образец, по образу и подобию которого создаются другие объекты. Объекты-копии могут сохранять связь с родительским объектом, автоматически наследуя изменения в прототипе; эта особенность определяется в рамках конкретного языка .
  • Вместо механизма описания классов и порождения экземпляров, язык предоставляет механизм создания объекта (путём задания набора полей и методов, которые объект должен иметь) и механизм клонирования объектов.
  • Каждый вновь созданный объект является «экземпляром без класса». Каждый объект может стать прототипом - быть использован для создания нового объекта с помощью операции клонирования . После клонирования новый объект может быть изменён, в частности, дополнен новыми полями и методами.
  • Клонированный объект либо становится полной копией прототипа, хранящей все значения его полей и дублирующей его методы, либо сохраняет ссылку на прототип, не включая в себя клонированных полей и методов до тех пор, пока они не будут изменены. В последнем случае среда исполнения обеспечивает механизм делегирования - если при обращении к объекту он сам не содержит нужного метода или поля данных, вызов передаётся прототипу, от него, при необходимости - дальше по цепочке.

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

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

Производительность объектных программ

Гради Буч указывает на следующие причины, приводящие к снижению производительности программ из-за использования объектно-ориентированных средств:

Динамическое связывание методов Обеспечение полиморфного поведения объектов приводит к необходимости связывать методы, вызываемые программой (то есть определять, какой конкретно метод будет вызываться) не на этапе компиляции, а в процессе исполнения программы, на что тратится дополнительное время. При этом реально динамическое связывание требуется не более чем для 20 % вызовов, но некоторые ООП-языки используют его постоянно. Значительная глубина абстракции ООП-разработка часто приводит к созданию «многослойных» приложений, где выполнение объектом требуемого действия сводится к множеству обращений к объектам более низкого уровня. В таком приложении происходит очень много вызовов методов и возвратов из методов, что, естественно, сказывается на производительности. Наследование «размывает» код Код, относящийся к «конечным» классам иерархии наследования, которые обычно и используются программой непосредственно, находится не только в самих этих классах, но и в их классах-предках. Относящиеся к одному классу методы фактически описываются в разных классах. Это приводит к двум неприятным моментам:

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

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

Критика ООП

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

Критические высказывания в адрес ООП:

  • Было показано отсутствие значимой разницы в продуктивности разработки программного обеспечения между ООП и процедурным подходом .
  • Кристофер Дэйт указывает на невозможность сравнения ООП и других технологий во многом из-за отсутствия строгого и общепризнанного определения ООП .
  • Александр Степанов в одном из своих интервью указывал, что ООП «методологически неправильно» и что «…ООП практически такая же мистификация, как и искусственный интеллект…» .
  • Фредерик Брукс указывает, что наиболее сложной частью создания программного обеспечения является «…спецификация, дизайн и тестирование концептуальных конструкций, а отнюдь не работа по выражению этих концептуальных конструкций…». ООП (наряду с такими технологиями как искусственный интеллект , верификация программ, автоматическое программирование, графическое программирование , экспертные системы и др.), по его мнению, не является «серебряной пулей», которая могла бы на порядок величины снизить сложность разработки программных систем. Согласно Бруксу, «…ООП позволяет сократить только привнесённую сложность в выражение дизайна. Дизайн остаётся сложным по своей природе…» .
  • Эдсгер Дейкстра указывал: «…то, о чём общество в большинстве случаев просит - это эликсир от всех болезней. Естественно, "эликсир" имеет очень впечатляющие названия, иначе будет очень трудно что-то продать: „Структурный анализ и Дизайн“, „Программная инженерия“, „Модели зрелости“, „Управляющие информационные системы“ (Management Information Systems), „Интегрированные среды поддержки проектов“, „Объектная ориентированность“, „Реинжиниринг бизнес-процессов “…» .
  • Никлаус Вирт считает, что ООП - не более чем тривиальная надстройка над структурным программированием, и преувеличение её значимости, выражающееся, в том числе, во включении в языки программирования всё новых модных «объектно-ориентированных» средств, вредит качеству разрабатываемого программного обеспечения.
  • Патрик Киллелиа в своей книге «Тюнинг веб-сервера» писал: «…ООП предоставляет вам множество способов замедлить работу ваших программ…».
  • Известная обзорная статья проблем современного ООП-программирования перечисляет некоторые типичные проблемы ООП [ ] .
  • В программистском фольклоре получила широкое распространение критика объектно-ориентированного подхода в сравнении с функциональным подходом с использованием метафоры «Королевства Существительных » из эссе Стива Йегги .

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

Критика рекламы ООП Критикуется явно высказываемое или подразумеваемое в работах некоторых пропагандистов ООП, а также в рекламных материалах «объектно-ориентированных» средств разработки представление об объектном программировании как о некоем всемогущем подходе, который магическим образом устраняет сложность программирования. Как замечали многие, в том числе упомянутые выше Брукс и Дейкстра, «серебряной пули не существует» - независимо от того, какой парадигмы программирования придерживается разработчик, создание нетривиальной сложной программной системы всегда сопряжено со значительными затратами интеллектуальных ресурсов и времени. Из наиболее квалифицированных специалистов в области ООП никто, как правило, не отрицает справедливость критики этого типа. Оспаривание эффективности разработки методами ООП Критики оспаривают тезис о том, что разработка объектно-ориентированных программ требует меньше ресурсов или приводит к созданию более качественного ПО. Проводится сравнение затрат на разработку разными методами, на основании которого делается вывод об отсутствии у ООП преимуществ в данном направлении. Учитывая крайнюю сложность объективного сравнения различных разработок, подобные сопоставления, как минимум, спорны. С другой стороны, получается, что ровно так же спорны и утверждения об эффективности ООП. Производительность объектно-ориентированных программ Указывается на то, что целый ряд «врождённых особенностей» ООП-технологии делает построенные на её основе программы технически менее эффективными, по сравнению с аналогичными необъектными программами. Не отрицая действительно имеющихся дополнительных накладных расходов на организацию работы ООП-программ (см. раздел «Производительность» выше), нужно, однако, отметить, что значение снижения производительности часто преувеличивается критиками. В современных условиях, когда технические возможности компьютеров чрезвычайно велики и постоянно растут, для большинства прикладных программ техническая эффективность оказывается менее существенна, чем функциональность, скорость разработки и сопровождаемость. Лишь для некоторого, очень ограниченного класса программ (ПО встроенных систем, драйверы устройств, низкоуровневая часть системного ПО, научное ПО) производительность остаётся критическим фактором. Критика отдельных технологических решений в ООП-языках и библиотеках Эта критика многочисленна, но затрагивает она не ООП как таковое, а приемлемость и применимость в конкретных случаях тех или иных реализаций её механизмов. Одним из излюбленных объектов критики является язык C++, входящий в число наиболее распространённых промышленных ООП-языков.

Объектно-ориентированные языки

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

Как правило, объектно-ориентированный язык (ООЯ) содержит следующий набор элементов:

  • Объявление классов с полями (данными - членами класса) и методами (функциями - членами класса).
  • Механизм расширения класса (наследования) - порождение нового класса от существующего с автоматическим включением всех особенностей реализации класса-предка в состав класса-потомка. Большинство ООЯ поддерживают только единичное наследование.
  • Полиморфные переменные и параметры функций (методов), позволяющие присваивать одной и той же переменной экземпляры различных классов.
  • Полиморфное поведение экземпляров классов за счёт использования виртуальных методов. В некоторых ООЯ все методы классов являются виртуальными.

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


Программирование-это теоретическая и практическая деятельность по созданию и сопровождению программы. Программа-описание алгоритма на языке, понятном ЭВМ.

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

Задача каждого программиста - создать хорошую программу, т.е. программу, которая:

А) надежна, т.е. зависит только от своих действий;

Б) универсальна, т.е. ее можно легко изменить, когда нужна переделка;

В) совместима, т.е. ее можно перенести с одного компьютера на другой с минимальными изменениями;

Г) удобочитаема, т.е. хорошо понимаема пользователем;

Д) эффективна, т.е. реализует наиболее эффективный способ решения задачи.

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


  1. ^ Области языков программирования. Научные приложения.
Первые цифровые компьютеры, появившиеся в 1940-х годах, использовались и фактически изобретались для научных целей. Обычно научные приложения имеют дело с простыми структурами данных и значительным количеством арифметических вычислений, выполняемых над числами с плавающей точкой. Наиболее часто употребляемыми структурами данных являются массивы и матрицы; из управляющих структур чаще других используются циклы со счетчиком и условные операторы. Первым языком, созданным для научных приложений, был язык FORTRAN. Язык ALGOL и большинство его потомков также предназначались для подобных целей. Однако для научных приложений особо важна эффективность, а ни один из созданных языков не оказался лучше языка FORTRAN. Также Matlab, R.

Требования: 1. Высокая скорость работы. 2. Поддержка различный математических типов 3. Векторные и матричные вычисления. 4. Большое кол-во математических функций.


  1. Области языков программирования. Коммерческие приложения.

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

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

Также RPG. Требования: 1. Поддержка обработки текста 2. Подд. Формирования отчётов 3. Точное описание числовых типов


  1. Области языков программирования. Искусственный интеллект.
Искусственный интеллект (ИИ) - обширная область применения компьютеров, отличающаяся использованием символьных, а не числовых вычислений. Под символьными вычислениями подразумевается манипулирование не с числами, а с символами. Кроме того, символьные вычисления удобнее производить с использованием связных списков данных, а не массивов. Символьные вычисления иногда требуют большей гибкости, чем другие области программирования. Например, в некоторых приложениях искусственного интеллекта очень удобно иметь возможность создавать и реализовывать фрагменты программы в процессе ее выполнения. Первым широко используемым языком программирования, созданным для применения в области искусственного интеллекта, был язык функционального программирования LISP, появившийся в 1959 году. Большинство программ в этой области были написаны именно на языке LISP или на одном из родственных языков. Однако в начале 1970-х годов возник альтернативный подход к решению этих задач - язык логического программирования Prolog (1997). Требования: 1. Неалгоритмический способ решения 2. Оперирование с символьными данными

  1. Области языков программирования. Системное программирование.
Операционные системы и все инструменты программной поддержки компьютерных систем называются системным программным обеспечением (system software). Оно используется практически повсеместно и, следовательно, должно эффективно функционировать. В связи с этим языки программирования, применяемые в этой области, должны обеспечивать быстрое выполнение программ. Более того, они должны иметь низкоуровневые свойства, позволяющие писать программы, осуществляющие взаимодействие с внешними устройствами. PL/S, BLISS- находящийся всего на один уровень выше языка ассемблера; Extended ALGOL. Некоторые характерные черты языка С способствуют его использованию в системном программировании. Он низкоуровневый, эффективно функционирует и не обременяет пользователя большим количеством ограничений. Тем не менее, некоторые считают язык С слишком опасным для использования в больших и важных системах программного обеспечения. Требование – скорость.

  1. ^ Области языков программирования. Языки сценариев.
Языки подготовки сценариев развивались постепенно в течение последних 25 лет. Программы на этих языках представляют собой исполняемые файлы, называемые сценариями, которые содержат перечень команд. Первым из таких языков был язык sh (сокр. от англ. shell - оболочка), первоначально состоявший из небольшого набора команд, интерпретируемых как вызовы системных подпрограмм, выполнявших служебные функции, например, управление файлами и их простую фильтрацию. Одни из наиболее мощных и широко известных языков подготовки сценариев - ksh, awk, tcl. Разработанный Ларри Уоллом (Larry Wall) язык Perl сначала представлял собой комбинацию языков sh и awk. После этого он получил значительное развитие и сейчас является мощным, хотя и несколько примитивным, языком программирования.

Требование: 1. Обработка текстовых данных 2. Широкая возможность интеграции программ.


  1. Области языков программирования. Web-программирование.
Веб-программирование - раздел программирования, ориентированный на разработку веб-приложений (программ, обеспечивающих функционирование динамических сайтов Всемирной паутины). Языки веб-программирования - это языки, которые в основном предназначены для работы с веб-технологиями. Языки веб-программирования можно условно разделить на две пересекающиеся группы: клиентские(JavaScript и VBScript)и серверные(PHP, SQL, Perl, JAVA).

Веб-программирование это:

Простой способ обновления и пополнения информации на сайте.

Возможность разнообразить сайт, добавив на него динамические разделы и интерактивные элементы: голосования, гостевые книги, форумы, игры,

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

Инструмент для решения любых задач по расширению функциональности сайта.

Требования: безопасность и обработка текстовой информации.


  1. ^ Уровни языков программирования. Машинные языки (история возникновения, отличительные особенности, пример языков). Вычислительные машины, служат для одной цели - для переработки информации, которая в них поступает. Переработку информации машина может произвести только тогда, когда четко изложена задача - что машина должна делать, и точно дан метод ее решения - как машина должна поступать. Она требует однозначности, конкретности, точности. И задачи переводят с человеческого языка на машинный.
МАШИННЫЙ ЯЗЫК - язык программирования для представления программ в форме, допускающей их непосредственную реализацию аппаратными средствами конкретной ЭВМ. Программа на машинном языке представляет собой последовательность машинных команд. Символами машинного языка являются двоичные цифры (0,1). Машинный код можно рассматривать как примитивный язык программирования или как самый низкий уровень представления скомпилированных или ассемблированных компьютерных программ. Хотя вполне возможно создавать программы прямо в машинном коде, сейчас это делается редко в силу громоздкости кода. Эффективность решения различных задач на ЦВМ в значительной степени зависит от того, насколько М. я. приспособлен для реализации заданных алгоритмов.

Особенности:

Для каждого процессора свой машинный язык

Выполняется непосредственно машиной

Минимальная (плохая) читаемость кода

Программисты почти не используют

^ 9. Уровни языков программирования. Языки ассемблера(история возникновения, отличительные особенности, пример языков).

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

Чтобы упростить общение человека с компьютером, были разработаны языки программирования типа Ассемблер, в которых переменные величины стали изображаться символическими именами, а числовые коды операций были заменены на словесные обозначения, которые легче запомнить. Язык программирования приблизился к человеческому языку, но удалился от языка машинных команд. Поэтому чтобы компьютер мог работать на языке Ассемблера, понадобился транслятор – программа, переводящая текст программы на Ассемблере в эквивалентные машинные команды. Языки типа Ассемблер являются машино-ориентированными, потому что они настроены на структуру машинных команд конкретного компьютера. Разные компьютеры с разными типами процессоров имеют разный Ассемблер.Особенности:

Набор команд языков ассемблера соответствует набору команд процессора

Более удобен для восприятия и кодирования

Компилируются/транслируются в машинный код.

^ 10. Уровни языков программирования. Языки высокого уровня(история возникновения, отличительные особенности, пример языков).

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

Языки высокого уровня отражают потребности программиста, но не возможности системы обработки данных. Программисты всеми силами пытались изобрести язык программирования, который по своей структуре будет схож с человеческим языком. Так появились языки программирования С, BASIC, Pascal, COBOL, FORTRAN и др. Эти языки обладали более простым кодом, поэтому создавать программы на них было легче и быстрее. Особенности:

Более понятны человеку

1 команда на языке высокого уровня – несколько машинных команд

Требуется перевести в машинный код

Проще писать сложную программу

11. Методы реализации программ. Компиляция (схема получения результата из исходного кода, преимущества и недостатки, сравнительная таблица).

Компиляция - трансляция программы, составленной на исходном языке высокого уровня, в эквивалентную программу на низкоуровневом языке, близком машинному коду (абсолютный код, объектный модуль, иногда на язык ассемблера). Язык, на котором представлена входная программа, называется исходным языком, а сама программа - исходным кодом. Выходной язык называется целевым языком или объектным кодом. Большинство компиляторов переводит программу с некоторого высокоуровневого языка программирования в машинный код, который может быть непосредственно выполнен процессором. Результат компиляции - исполнимый модуль - обладает максимальной возможной производительностью, однако привязан к определённой операционной системе и процессору (и не будет работать на других). Для каждой целевой машины (IBM, Apple, Sun и т. д.) и каждой операционной системы или семейства операционных систем, работающих на целевой машине, требуется написание своего компилятора.


Критерий

Компиляция

Смешанная реализация

Интерпретация

Скорость исполнения

наивысшая

средняя

низкая


плохая

отличная

отличная


низкое

среднее

высокое


неудобно

терпимо

очень удобно

Примеры

Pascal, c, c++

Java, VB

Python, VBA, PHP

12. Методы реализации программ. Интерпретация (схема получения результата из исходного кода, преимущества и недостатки, сравнительная таблица).

Интерпретация – выполнение исходного текста программы. Достоинства : Бо́льшая переносимость интерпретируемых программ - программа будет работать на любой платформе, на которой есть соответствующий интерпретатор. Упрощение отладки исходных кодов программ. Меньшие размеры кода по сравнению с машинным кодом, полученным после обычных компиляторов. Недостатки: Интерпретируемая программа не может выполняться отдельно без программы-интерпретатора. Сам интерпретатор при этом может быть очень компактным. Интерпретируемая программа выполняется медленнее, поскольку промежуточный анализ исходного кода и планирование его выполнения требуют дополнительного времени в сравнении с непосредственным исполнением машинного кода, в который мог бы быть скомпилирован исходный код.

Алгоритм работы простого интерпретатора


  • прочитать инструкцию;

  • проанализировать инструкцию и определить соответствующие действия;

  • выполнить соответствующие действия;

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

Критерий

Компиляция

Смешанная реализация

Интерпретация

Скорость исполнения

наивысшая

средняя

низкая

Переносимость (кросс-платформеность)

плохая

отличная

отличная

Использование ресурсов (оперативная память, жесткий диск)

низкое

среднее

высокое

Удобство разработки и сопровождения (поиск ошибок)

неудобно

терпимо

очень удобно

Примеры

Pascal, c, c++

Java, VB

Python, VBA, PHP

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

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


Критерий

Компиляция

Смешанная реализация

Интерпретация

Скорость исполнения

наивысшая

средняя

низкая

Переносимость (кросс-платформеность)

плохая

отличная

отличная

Использование ресурсов (оперативная память, жесткий диск)

низкое

среднее

высокое

Удобство разработки и сопровождения (поиск ошибок)

неудобно

терпимо

очень удобно

Примеры

Pascal, c, c++

Java, VB

Python, VBA, PHP

14. Методы реализации программ. Трансляция (схема получения результата из исходного кода, преимущества и недостатки, сравнительная таблица).

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

1.Лексический анализ. На этом этапе последовательность символов исходного файла преобразуется в последовательность лексем.

2.Синтаксический (грамматический) анализ. Последовательность лексем преобразуется в дерево разбора.

3.Семантический анализ. Дерево разбора обрабатывается с целью установления его семантики (смысла) - например, привязка идентификаторов к их декларациям, типам, проверка совместимости, определение типов выражений и т. д. Результат обычно называется «промежуточным представлением/кодом», и может быть дополненным деревом разбора, новым деревом, абстрактным набором команд или чем-то ещё, удобным для дальнейшей обработки.

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

5.Генерация кода. Из промежуточного представления порождается код на целевом языке.

^ 15. Критерии качества программ:

Количественные:

1)Размер программы;

А) В исходном коде LOC(~30,50);

Б) В откомпилированном виде;

Потребляемые ресурсы;

Время выполнения;

Качественные:

Корректность (программа должна выполнять поставленную задачу);

Удобство;

Читабельность (Читаемость кода);

Сопровождение (расширяемость);

Переносимость;

Надежность;

16. Алгоритм:

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

Основные свойства алгоритмов следующие:

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

2. Дискретность (прерывность, раздельность) - алгоpитм должен пpедставлять процесс решения задачи как последовательное выполнение пpостых (или pанее определённых) шагов (этапов).

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

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

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

^ 17. Способы записи алгоритма. Блок-схемы.

Графический способ представления алгоритмов является более компактным и наглядным по сравнению со словесным.

При графическом представлении алгоритм изображается в виде последовательности

Связанных между собой функциональных блоков, каждый из которых соответствует

Выполнению одного или нескольких действий.

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

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

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

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

^ 18. Способы записи алгоритма. Псевдокод.

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

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

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

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

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

^ 19. Способы записи алгоритма. Сравнение различных подходов:

Графический способ представления алгоритмов является более компактным и наглядным по сравнению со псевдокодом. При графическом представлении алгоритм изображается в виде последовательности связанных между собой функциональных блоков. Графическое описание алгоритма, называется блок-схемой. Этот способ имеет ряд преимуществ благодаря наглядности, обеспечивающей, в частности, высокую «читаемость» алгоритма и явное отображение управления в нем. В блок-схеме каждому типу действий (вводу исходных данных, вычислению значений выражений, проверке условий, управлению повторением действий, окончанию обработки и т.п.) соответствует геометрическая фигура, представленная в виде блочного символа. Блочные символы соединяются линиями переходов, определяющими очередность выполнения действий. В таблице №1 приведены обозначения, наиболее часто используемые в блок-схемах. Сначала определим понятие блок-схемы. Блок-схема - это ориентированный граф, указывающий порядок исполнения команд алгоритма. Вершины такого графа могут быть одного из трех типов: функциональная вершина (F), имеющая один вход и один выход; предикатная вершина (Р), имеющая один вход и два выхода, в этом случае функция Р передает управление по одной из ветвей в зависимости от значения Р (t, т. е. true, означает «истина»,f, т. е. false, - «ложь»); объединяющая вершина (вершина «слияния») (U), обеспечивающая передачу управления от одного из двух входов к выходу. Иногда вместо t пишут «да» (либо знак «+»), вместо f - «нет» (либо знак «-»). Из данных элементарных блок-схем можно построить четыре блок-схемы, имеющих особое значение для практики алгоритмизации: композиция, или следование альтернатива, или ветвление; итерация, или цикл, с предусловием или постусловием. Блок-схема альтернатива может иметь и сокращенную форму, в которой отсутствует ветвь F2. Развитием блок-схемы типа альтернатива является блок-схема выбор.

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

1. Трассировка

2. Контрактное программирование, в частности проверка пред и пост условий

3. Обработка ошибок.

4. Реализация систем безопасности.

Динамические языки

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

Больше подходят для быстрой разработки приложений.

Phyton,PHP,Rudy,Javascript.

Операция склеивания строк – конкатенация.

[Объектно-ориентированные языки программирования ]

Объект – объединяет в себе поля данных (атрибуты) и методы (выполняемые объектом действия).

Программа – описание объектов, их свойств (атрибутов), совокупностей (классов), отношений между ними, способов их взаимодействий и операций над объектами (методов), при этом классы образуют иерархию.

Наследование – Создание нового класса объектов путем добавления новых элементов (методов).

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

Типизация – позволяет устранить ошибки на момент компиляции.

Объекты, классы и методы могут быть полиморфными данными, следовательно гибкость и универсальность.

Сложность адекватной формализации объектной теории, следовательно трудность тестирования и верификации ПО.

С++, Ada, pascal, PHP.

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

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

Язык описания интерфейсов

Похож на описание классов С++.

Язык спецификаций.

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

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

Программа – совокупность логических правил при высказывании.

Используется в экспертных системах и системах принятия решений.

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

Prolog,Oz,Frill.

Специфичность решаемых задач.



Нелинейность структуры программы.

Сложность эффективной реализации в системе реального времени.

Параллельное программирование

Программы – совокупность описаний процессов, которые могут выполняться как в действительности одновременно, так и в псевдопараллельном режиме.

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

Часто применяют в системах реального времени.

Недостаток – высокие накладные расходы на разработку программ.

Язык сценариев (скриптовые)

Программа состоит из сценариев, последовательностей операций.

Скриптовые языки или языки сценариев пакетной обработки.

8. Унификация и хорновский клоз в логических языках программирования .

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

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

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



Унификация - При поиске решений для множеств ограничений мы используем идею, высказанную Хиндли (Hindley, 1969) и Милнером (Milner, 1978), кото- рая состоит в использовании унификации (unification) (Robinson, 1971) для проверки непустоты множества решений и, если это так, нахожде- ния «наилучшего» из его элементов в том смысле, что все остальные решения могут быть непосредственно получены из него.

Дизъюнкт Хорна (хорновский дизъюнкт, клоз Хорна) - дизъюнкция, в которой содержится не более одного положительного литерала.

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

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

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

Пролог пытается отождествить термы при доказательстве, или согласовании, целевого утверждения. Например, в программе для согласования запроса?- человек(Х) целевое утверждение человек(X) может быть отождествлено с фактом служащий(Иван), в результате чего переменная Х станет конкретизированной: Х= Иван.

Хорновский клоз (Ноrn clause) - это формула, в которой с помощью конъюнкции («и») элементарных формул выводится одиночная элементарная формула:

(s=>t)<=(t = tl||t2)^(s=>tl)

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

Чтобы инициализировать вычисление логической программы, задается цель:

“wor” => "Hello world"?

Машина вывода пытается сопоставить цель и вывод формулы. В данном случае соответствие устанавливается сразу же: "wor" соответствует переменной s, a "Hello world" - переменной t. Это определяет подстановку выражений (в данном случае констант) для переменных; подстановка применяется ко всем переменным в формуле:

"wor" => "Hello world" <= ("Hello world" = tl || t2) ^ ("wor" => tl)

Теперь мы должны показать, что:

("Hello world" = t1|| t2) ^ ("wor" => tl)

является истинным, и это ведет к новому соответствию образцов, а именно попытке установить соответствие "Hello world" с tl || t2. Здесь, конечно, может быть много соответствий, что приведет к поиску. Например, машина вывода может допускать, чтобы tl указывало на "Не", a t2 указывало на "llо world"; эти подстановки затем проводятся во всем вычислении.

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

10. Языки программирования низкого уровня .

Язык программирования низкого уровня - язык программирования, близкий к программированию непосредственно в машинных кодах используемого реального или виртуального (например, Java, Microsoft .NET) процессора. Для обозначения машинных команд обычно применяется мнемоническое обозначение. Это позволяет запоминать команды не в виде последовательности двоичных нулей и единиц, а в виде осмысленных сокращений слов человеческого языка (обычно английских).

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

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

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

Намечают три вида низкоуровневых языков

1 Машинный код

2 Мнемо код

3 Ассемблер, макроассемблер

Машина Кода программа представляется в виде последовательности чисел являющихся кодами команд процессора, адресами оперативной памяти, номерами регистров процессора и внешних устройств.

Позволяют вместо чисел использовать символьный имена, отражающие смысл выполняемой команды.

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

Макроассемблеры является расширением ассемблера за счет включения макросредств.

11. Средства разработки графического интерфейса пользователя. Эргономические свойства человеко-машинного интерфейса .

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

Эргономичность - интегральный показатель степени выполнения эргономических требований;

Показатели качества деятельности оператора (время решения задачи, производительность, число ошибок, состояние здоровья и т.д.);

Надёжность деятельности оператора (своевременное и безошибочное выполнение функций);

Эффективность СЧМ;

Напряжённость и экстремальность деятельности и т.д.

Человеко-машинный интерфейс - это широкое понятие, охватывающее инженерные решения, обеспечивающие взаимодействие оператора с управляемыми им машинами. Создание систем человеко-машинного интерфейса тесно связано с эргономикой (Эргономика - научная дисциплина, комплексно изучающая производственную деятельность человека и ставящая целью её оптимизацию), но не тождественно ей. Проектирование ЧМИ включает в себя создание рабочего места: кресла, стола, или пульта управления, размещение приборов и органов управления, освещение рабочего места, а, возможно, и микроклимат. Далее рассматриваются действия оператора с органами управления, их доступность и необходимые усилия, согласованность (непротиворечивость) управляющих воздействий и "защита от дурака", расположение дисплеев и размеры надписей на них.

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

Человеко-машинный интерфейс условно можно разделить на 3 подгруппы:

текстовый (командные строки) интерфейс;

смешанный (псевдографический) интерфейс

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

графический интерфейс

(это система средств для взаимодействия пользователя с компьютером, основанная на представлении всех доступных пользователю системных объектов и функций в виде графических компонентов экрана (окон, значков, меню, кнопок, списков и т.п.) К этому виду интерфейсов относятся такие системы как, Mac OS, Solaris, GNU/Linux, Microsoft Windows, NeXTSTEP

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

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

К процедурным языкам относятся Basic, Cobol, Fortran, Pascal, C и Ada.

Преимущества:

Маленькие модули можно написать легко и быстро;

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

Модули можно отлаживать и тестировать независимо от всей программы.

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

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

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

Примеры: паскаль, С, Бейсик, Ада, Фортран.

13. Обоснование выбора языка программирования .

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

Язык программирования служит двум связанным между собой целям: он дает программисту аппарат для задания действий, которые должны быть выполнены, и формирует концепции, которыми пользуется программист, размышляя о том, что делать. Первой цели идеально отвечает язык, который настолько «близок к машине», что всеми основными машинными аспектами можно легко и просто оперировать достаточно очевидным для программиста образом. С таким умыслом первоначально задумывался C. Второй цели идеально отвечает язык, который настолько «близок к решаемой задаче», чтобы концепции её решения можно было выражать прямо и коротко. С таким умыслом предварительно задумывались средства, добавленные к C для создания С++.

Главным образом выбор языка программирования зависит от

1. Решаемой задачи

2. Операционной системы

3. Возможностей языка программирования

4. Цена программного обеспечения

5. Обучение

6. Сопровождение

7.Удобство

8. Возможности и условия дальнейшего распространения готового продукта

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

Недостатки:

Язык компилируется в момент исполнения кода. Каждый раз, когда вы открываете сайт, javascript код начинает компилироваться. Как минимум увеличивается время выполнения программы.

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

Не привычная для многих программистов объектная модель. Классы и наследование классов присутствует, но оно сильно отличается от привычной многим реализаций в языках программирования C++/C#/Java.

Достоинства:

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

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

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

14. Перегрузка в языках программирования .

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

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

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

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

Чтобы дать возможность определять и переопределять операции в язык вводятся различные синтаксические конструкции.

Перегружать операции имеет смысл только в том случае, если вновь вводимые операции аналогичны предопределенным.

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

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

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

Int add_values(int a, int b)

{ return(a + b);}

Int add_values(int a, int b, int c)

{ return(a + b+c);}

Int add_values(float a, float b)

{ return(a + b);}

{cout<<”200+800=”<< add_values (200,800);

cout<<”100+200+800=”<< add_values (100,200,800);

cout<<”0.5+0.2=”<< add_values (0.5,0.2);}

Механизм реализации в языке :

Улучшает удобочитаемость программ/

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

Варианты решения:

1. Требовать однозначный проходящий вариант перегруженной функции.

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

Приоритет и ассоциативность – порядок выполнения и следование операторов.

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

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

Пример: операция a+b все нормально для чисел, но для строк важен порядок, т.к. это конкатенация и a+b!=b+a

15. Логические языки программирования. Основные положения и понятия. Отличия от других типов языков программирования .

Логические языки – все операции представлены в виде логических формул. В программе допустимы логические причинно следственные связи. Таким образом логические программы базируются на классической логике и применимы для систем логического вывода.

Преимущества

1) Высокий уровень машинной независимости

2) Возможность откатов (возвращение к предыдущей подцели, и отрицательного в результате анализа одного из вариантов в процессе поиска решения)

Недостатки

1) Специфичность класса решаемых задач.

2) Сложность эффективной реализации для принятия решения в реальном времени.

3) Нелинейность структуры программы.

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

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

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

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

· Задача программиста – описание логической модели предметной области в терминах объектов, их свойств и отношений между ними (без деталей): описание данных и логики их обработки ~ аналогия с ООП.

· Удобство описания отношений между объектами (реляционная модель).

· Компактность кода (обработка структурированных данных, лог. правила).

· Возможность перебора и поиска различных решений, заложенная в язык.

· Легкость понимания (описание отд. правил), отладки программ (trace).

· Легкость описания сложных структур данных (деревья, списки и т.п.).

· Эффективный метод вычислений – рекурсия.

· Отсутствие указателей, операторов присваивания и безусловного перехода.

· Множество областей для применения: автоматический перевод, обработка текстов, экспертные системы, САПР, Data-minig системы, автоматическое управление, СУБД, символьные вычисления.

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

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

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

Преимущества

1) Концептуальная близость к предметной области. Произвольные структуры и назначения.

2) Поддержка механизма обработки событий, которые изменяют атрибуты объектов, и моделирует их взаимодействие в предметной области.

3) Использование раннее разработанных библиотек объектов и методов, что снижает трудозатраты и временные затраты.

4) Объекты классы и методы могут быть полиморфными, что делает программное обеспечение более гибким и универсальным.

Недостаток

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

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

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

(ООP) (объектно-ориентированное программирование) – это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.

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

(OOA) (Объектно-ориентированный анализ) – это методология, при которой требования к системе воспринимаются с точки зрения классов и объектов, выявленных в предметной области.

Связь: OOA→OOP→OOD

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

ОО ЯП

Язык программирования является объектно-ориентированным тогда и только тогда, когда выполняются следующие условия:

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

2) Объекты относятся к соответствующим типам (классам).

3) Типы (классы) могут наследовать атрибуты супер типов (суперклассов).

Преимущества объектной модели:

Позволяет использовать возможности ОО языка программирования.

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

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

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

Ориентирована на человеческое восприятие мира.

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

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

· Данные и операции вместе образуют определенную сущность и они не «размазываются» по всей программе, как это нередко бывает в случае процедурного программирования.

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

· Инкапсуляция информации защищает наиболее критичные данные от несанкционированного доступа.

Недостатки:

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

17. Полиморфизм в объектно-ориентированном программировании. Виртуальные функции. Таблицы виртуальных функций .

Полиморфизмом называется способность функции обрабатывать данные разных типов.

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

Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.

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

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

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

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

Виртуальные функции - применяются для реализации динамического полиморфизма

Чистая виртуальная функция – это функция-член, которая объявлена со спецификатором = 0 вместо тела:

Чистая виртуальная функция не имеет определения и не может быть непосредственно вызвана.

Чистая виртуальная функция применяется для создания абстрактных классов.

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

Функция – член объявляется чистой виртуальной тогда, когда ее определение для базового класса не имеет смысла.

Механизм работы virtual

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

Количество элементов в массиве равно количеству виртуальных функций в массиве.

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

Помимо создания таблицы виртуальных функций, в базовом классе объявляется поле __vfptr – указатель на vtable. Этот указатель наследуется всеми производными классами. __vfptr указывает на vtable класса, которому принадлежит объект.

Если процессор видит, что метод виртуальный, то ищет в таблице нужную запись. Адрес таблицы он узнает через __vfptr.

Абстрактный класс

Абстрактный класс – такой, у которого есть хотя бы одна не переопределенная чистая виртуальная функция – член.

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

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

Виртуальный деструктор

Основное правило: если у вас в классе присутствует хотя бы одна виртуальная функция, деструктор также следует сделать виртуальным.

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

Если этого не сделать, в программе будут утечки памяти.

Полиморфи́зм (от греч. πολὺ- - много, и μορφή - форма) в языках программирования - возможность объектов с одинаковой спецификацией иметь различную реализацию.

Возможность объектов с одинаковой спецификацией иметь различную реализацию.

Предполагает использование одного объекта языка, для выполнения различных действий.

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

Различают полиморфизм статический и динамический.[ В статическом полиморфизме множественные формы разрешаются на этапе компиляции.

1) Преобразование типов

2) Перегрузка

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

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

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

Таблица виртуальных функций – это одномерный массив указателей на функции. Количество элементов в массиве равно количеству виртуальных функций в классе.

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

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

18. Структура языка программирования. Синтаксис и семантика языков программирования. Расширенная форма Бэкуса-Наура .

{Основные элементы языка программиро

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

Клиентские языки

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

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

Самым распространенным из клиентских языков является Netscape совместно с компанией Sun Microsystems . Другой вариант клиентского языка это, например, VBScript .

Серверные языки

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

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

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


Wikimedia Foundation . 2010 .

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

Что такое ООП

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

  • инкапсуляция;
  • наследование;
  • полиморфизм.

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

Примеры объектно-ориентированных языков:

  1. Pascal. С выходом Delphi 7 на официальном уровне стал называться Delphi. Основная область использования Object Pascal - написание прикладного ПО.
  2. C++ широко используется для разработки программного обеспечения, является одним из самых популярных языков. Применяется для создания ОС, прикладных программ, драйверов устройств, приложений, серверов, игр.
  3. Java - транслируется в байт-код, обрабатывается виртуальной машиной Java. Преимуществом такого способа выполнения является независимость от операционной системой и оборудования. Существующие семейства: Standard Edition, Enterprise Edition, Micro Edition, Card.
  4. JavaScript применяется в качестве языка сценариев для web-страниц. Синтаксис во многом напоминает Си и Java. Является реализацией Ecmascript. Сам Ecmascript используется в качестве основы для построения других таких как JScript, ActionScript.
  5. Objective-C построен на основе языка Си, а сам код Си понятен компилятору Objective-C.
  6. Perl - высокоуровневый интерпретируемый динамический язык общего назначения. Имеет богатые возможности для работы с текстом, изначально разработан именно для манипуляций с текстом. Сейчас используется в системном администрировании, разработке, сетевом программировании, биоинформатике и т. д.
  7. PHP. Аббревиатура переводится как препроцессор гипертекста. Применяется для разработки веб-приложений, в частности серверной части. С его помощью можно создавать gui-приложения с помощью пакетов WinBinder.
  8. Python - язык общего назначения, ориентирован на повышение производительности разработчика и читаемость кода. Был разработан проект Cython, с помощью которого осуществляется трансляция программ, написанных на Python в код на языке Си.

Абстракция

Любая книга из рода “Объектно-ориентированное программирование для чайников” выделяет один из главных принципов - абстракцию. Идея состоит в разделении деталей или характеристик реализации программы на важные и неважные. Необходима для крупных проектов, позволяет работать на разных уровнях представления системы, не уточняя детали.

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

Известный афоризм Дэвида Уилера гласит: Все проблемы в информатике можно решить на другом уровне абстракции.

Наследование

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

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

Существует несколько типов наследования:

  • простое;
  • множественное.

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

Наследование выглядит так:

function draw() {

return "just animal";

function eat() {

return "the animal is eating";

class Cow extends Animal {

function draw() {

Return "something that looks like a cow";

Видим, что class Cow унаследовал все методы от class Animal. Теперь, если выполнить Cow.eat(), получаем "the animal is eating", соответственно, метод draw() изменен. Cow.draw() вернет “something that looks like a cow”, а Animal.draw() вернет “just animal”.

Инкапсуляция

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

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

function __construct($name) {

$this->name = $name;

function getName() {

return $this->name;

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

Полиморфизм

Полиморфизм позволяет использовать одно и то же имя для решения схожих, но технически разных задач.

В примере выше находится таблица. Мы видим class CardDesk и class GraphicalObject. У обоих есть функция под названием draw(). Она выполняет разные действия, хотя имеет одно имя.

Ad hoc полиморфизм или специальный полиморфизм использует:

  • перегрузку функций, методов;
  • приведение типов.

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

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

«Один интерфейс — много реализаций» Бьерн Страуструп.

Класс

Класс - это такой тип данных, который состоит из единого набора полей и методов.

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

  • наследования;
  • ассоциации;
  • агрегации.

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

Одной из главных характеристик является область видимости. Понятие по-разному определяется разными ЯП.

В Object Pascal описывается следующим образом:

ClassName = class(SuperClass)

{ использование элементов ограничивается только пределами модуля }

{ здесь указываются поля }

{ спецификатор доступа стал доступным с выходом Delphi 2007, обозначает то же, что и private }

{ элементы могут использоваться внутри ClassName или при наследовании }

{ элементы доступны всем, они отображаются в Object Inspector"e }

Здесь SuperClass - предок, от которого происходит наследование.

Для C++ создание выглядит так:

class MyClass: public Parent

MyClass(); // конструктор

~MyClass(); // деструктор

В этом примере Parent является предком, если таковой имеется. Спецификаторы private, public, protected обозначают то же самое, что в предыдущем примере на Паскале. Также мы видим конструктор, деструктор, доступные для любой части программы. У C++ все элементы по умолчанию являются private, соответственно, это можно не указывать.

Особенности реализации

В центре объектно-ориентированных языков - объект, он является частью класса. Он состоит из:

  • поля;
  • метода.

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

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

ООП-методологии

Существуют такие методологии:

  • Компонентно-ориентированное программирование;
  • Прототипное программирование;
  • Классоориентированное программирование.

Компонентно-ориентированное программирование опирается на понятие компонента - такого составляющего программы, которое предназначено для повторного использования. Реализуется как множество конструкций с общим признаком, правилами, ограничениями. Подход используется в объектно-ориентированном языке Java, где компонентная ориентация реализуется посредством “JavaBeans”, написанных по одним правилам.

В прототипном программировании нет понятия класса - наследование производится за счет клонирования существующего прототипа. Это основа объектно-ориентированных языков javascript и других диалектов ecmascript, а также lua или lo. Главные особенности:

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

Классоориентированное программирование фокусируется на и экземпляр. Класс определяет общую структуру, поведение для экземпляров, которые их перенимают.

Объектно-ориентированные языки

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

ООЯ обязательно содержит набор следующих элементов:

  • объявление классов с полями, методами;
  • расширение за счет наследования функций;
  • полиморфное поведение.

Кроме вышеперечисленного списка, могут быть добавлены дополнительные средства:

  • конструктор, деструктор, финализаторы;
  • свойства;
  • индексаторы;
  • модификаторы доступа.

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

ЯП поддерживают больше, чем одну парадигму. Например, PHP или JavaScript поддерживают функциональное, процедурное, объектно-ориентированное программирование. Java работает с пятью парадигмами: объектно-ориентированной, обобщенной, процедурной, аспектно-ориентированной, конкурентной. C# считается одним из самых успешных примеров мультипарадигмальности. Он поддерживает те же подходы, что Java, к этому списку добавляется еще рефлексивная парадигма. Такой ЯП, как Oz, разработан для того, чтобы объединить все понятия, традиционно связанные с различными программными парадигмами.