Файл: История и развитие методологии объектно-ориентированного программирования. Сферы ее применения..pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 20.05.2023

Просмотров: 349

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

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

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

При описании интерфейса компонента важна не только сигнатура операций, которые можно выполнять с его помощью. Становится важным и то, какие другие компоненты он может задействовать при работе, а также каким ограничениям должны удовлетворять входные данные операций и какие свойства выполняются для результатов их работы. Эти ограничения являются так называемым интерфейсным контрактом или программным контрактом компонента. Интерфейс компонента включает набор операций, которые можно вызвать у любого компонента, реализующего данный интерфейс, и набор операций, которые этот компонент может вызвать в ответ у других компонентов. Интерфейсный контракт для каждой операции самого компонента (или используемой им) определяет предусловие и постусловие ее вызова. Предусловие операции должно быть выполнено при ее вызове, иначе корректность результатов не гарантируется. Если эта операция вызывается у компонента, то обязанность позаботиться о выполнении предусловия лежит на клиенте, вызывающем операцию. Если же эта операция вызывается компонентом у другого компонента, он сам обязуется выполнить это предусловие. С постусловием все наоборот — постусловие вызванной у компонента операции должно быть выполнено после ее вызова, и это — обязанность компонента. Постусловие операции определяет, какие ее результаты счита ются корректными. В отношении вызываемых компонентом операций выполнение их постусловий должно гарантироваться теми компонентами, у которых они вызываются, а вызывающий компонент может на них опираться в своей работе.[50] Компонентно-ориентированный подход может применяться во многих языках программирования, с помощью стандартных конструкций (таких как: классы, интерфейсы, пакеты, модули).


Существуют языки программирования, реализующие на конструктивном уровне компонентно-ориентированное программирование:

«Оберон» (ограниченно);

«Компонентный Паскаль».

В рамках языка «Java» — компонентно-ориентированное программирование реализуется посредством компонентов, называемых «JavaBeans», поддержанных в одной из ранних спецификаций языка;

В платформе «.NET» — реализован компонентно-ориентированный подход, обеспечивающий создание и повторное использование компонентов для любого языка программирования, поддерживаемого платформой.[51]

Рис. 1.0 «Основные элементы компонентного программного обеспечения»

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

Источник: «НОУ Интуит Лекция 12: Компонентные технологии и разработка распределенного ПО.» URL:[ http://www.intuit.ru/studies/courses/64/64/lecture/1888]

Компоненты отличаются от классов объектно-ориентированных языков:

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

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

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

Возможность включения и исключения компонента из системы делает его отдельным элементом продаваемого ПО. Компоненты, хотя и не являются законченными продуктами, могут разрабатываться и продаваться отдельно, если они следуют правилам определенной компонентной модели и реализуют достаточно важные для покупателей функции, которые те хотели бы иметь в рамках своей программной системы. Надо отметить, что, хотя рынок ПО существует достаточно давно, а компонентные технологии разрабатываются уже около 20 лет, рынок компонентов развивается довольно медленно. Поставщиками компонентов становятся лишь отдельные компании, тесно связанные с разработчиками конкретных компонентных сред, а не широкое сообщество индивидуальных и корпоративных разработчиков, как это представляли себе создатели компонентных технологий при их зарождении. По-видимому, один из основных факторов, мешающих развитию этого рынка, — это "гонка технологий" между поставщиками основных компонентных сред. Ее следствием является отсутствие стабильности в их развитии. Новые версии появляются слишком часто, и достаточно часто при выходе новых версий изменяются элементы компонентной модели. Так что при разработке компонентов для следующей версии приходится следовать уже несколько другим правилам, а старые компоненты с трудом могут быть переиспользованы.[52]


Еще одним стилем объектно-ориентированного программирования является прототипное программирование. Главное отличие от ООП заключается в том, что понятие класса отсутствует, а наследование производится путём клонирования существующего экземпляра объекта — прототипа.[53]

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

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

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

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

Языками программирования, поддерживающими прототипную парадигму программирования, являются: ECMAScript, Falcon, Io, Lua.[55]

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


4. Критика объектно-ориентированного программирования

Несмотря на широкое распространение методологии объектно-ориентированного программирования, данная парадигма подвергается критике по некоторым причинам, включая несоответствие заявленным целям о повторном использовании и модульности[56], а так же преувеличении важности одних парадигм (таких, как классы и объекты) над важными аспектами (процедуры, алгоритмы).

Так, Лука Карделли утверждает, что объектный код «по своей сути менее эффективен», чем процедурный код, в объектно-ориентированном программировании уходит больше времени на компиляцию, в сравнении с процедурной парадигмой. По словам Карделли, языки ООП обладают «крайне плохими свойствами модульности по отношению к расширению и модификации классов» и имеют тенденцию быть чрезвычайно сложными. С последним утверждением солидарен Джо Армстронг, создатель функционально-ориентированного языка Erlang, которому принадлежит цитата:

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

Исследование Potok et al. Не показало существенной разницы в производительности между объектно-ориентированным и процедурным программированием.[58]

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

Объектно-ориентированное программирование было раскритиковано российским учёным в области информатики Александром Степановым:

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


Я нахожу объектно-ориентированное программирование философски нездоровым. Оно утверждает, что всё является объектом. Даже если это так, это не очень интересно: сказать, что всё является объектом -- значит, не сказать вообще ничего. Я нахожу объектно-ориентированное программирование неправильным методологически. Оно начинается с классов. Это как если бы математик начал с аксиом. Вы не начинаете с аксиом -- вы начинаете с доказательств. Только когда вы нашли кучу соотносящихся доказательств, вы предлагаете аксиомы. Вы заканчиваете аксиомами.То же справедливо и в программировании: вы должны начать с интересных алгоритмов. Только когда вы хорошо их понимаете, вы можете предложить интерфейс, который позволит им работать».[60]

Пол Грэм предположил, что популярность ООП в крупных компаниях объясняется «большими (и часто меняющимися) группами посредственных программистов». По словам Грэма, дисциплина, навязанная ООП, не позволяет программисту «совершить много ошибок». [61]

Стив Йегге отметил, что в ООП отличие от функционального программирования: [62]

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

Ричард Хики, создатель Clojure, описал объектные системы как чрезмерно упрощенные модели реального мира. Он подчеркнул неспособность ООП правильно моделировать время, что становится все более проблематичным по мере того, как программные системы продолжают конкурировать.[63]

Роб Пайк, программист, принимавший участие в создании UTF-8 и Go, назвал объектно-ориентированное программирование «римскими цифрами среди программирования» сказав, что языки ООП часто переводят внимание со структур данных и алгоритмов на типы данных. [64] Пайк приводит в пример случай с неким профессором, чьё «идиоматическое» решение проблемы было создание новых шести классов, вместо того, чтобы просто применить таблицу поиска.[65]

Эрик Раймонд, программист Unix-систем и сторонник программного обеспечения с открытым исходным кодом опроверг заявления о том, что современное объектно-ориентированное программирование является «единственным верным решением». Сообщив, что объектно-ориентированные языки программирования имеют тенденцию стимулировать многоуровневые программы, плохо влияющие на чистоту языка (программирования). Раймонд критикует методологию ООП, сравнивая её с подходом, используемым в Unix и языке программирования C. [66]