Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

История и развитие методологии объектно-ориентированного программирования. Сферы применения (История и развитие методологии ООП. Сфера применения)

Содержание:

Введение

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

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

Глава 1. История и развитие методологии ООП. Сфера применения

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

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

На заре появления вычислительных машин программирование, как область знания, находилось в зачаточном состоянии. Первые программы создавались посредством переключателей на панели компьютера. Очевидно, что такой способ подходил только для небольших программ. Затем программы стали писать на языке машинных команд, а изобретение ассемблера позволило писать уже сравнительно длинные программы. Следующий шаг был сделан в 1950 году, когда был создан первый язык программирования высокого уровня Фортран.[1]

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

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

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

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

Модуль ООП — файл описаний объектов и действий над ними.

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

Объектно-ориентированное мышление адекватно способу естественного человеческого мышления, ибо человек мыслит "образами" и "абстракциями". Чтобы проиллюстрировать некоторые из принципов объектно-ориентированного мышления, обратимся к следующему примеру, основанному на аналогии мира объектов реальному миру.[3]

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

Таким образом, для решения своей проблемы вы нашли объект "кассир железнодорожной кассы" и передали ему сообщение, содержащее запрос. Обязанностью объекта "кассир железнодорожной кассы" является удовлетворение запроса.

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

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

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

Кассир, находящийся на рабочем месте, не обязан отвлекаться от работы для пустой болтовни с покупателем билета, например, сообщать ему свой домашний телефон или сумму денег, находящуюся в сейфе кассы. Таким образом, кассир взаимодействует с другими объектами ("покупатель билета", "автоматизированная система", "инкассатор", "бригадир" и т. д.) только по строго регламентированному интерфейсу. Интерфейс — это набор форматов допустимых сообщений. Для исключения возможных, но недопустимых сообщений используется механизм сокрытия информации (инструкция, запрещающая кассиру болтать впустую на рабочем месте).[4]

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

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

Вы можете передать свое сообщение, например, объекту "свой приятель", и он его, скорее всего, поймет, и как результат — действие будет выполнено (а именно билеты будут куплены). Но если вы попросите о том же объект "продавец магазина", у него может не оказаться подходящего метода для решения поставленной задачи. Если предположить, что объект "продавец магазина" вообще воспримет этот запрос, то он "выдаст" надлежащее сообщение об ошибке. В отличие от программ, люди работают не по алгоритмам, а по эвроритмам. Человек может самостоятельно менять правила методов своей работы. Так, продавец магазина при виде аргумента "очень большая сумма", может закрыть магазин и побежать покупать железнодорожный билет. Напомним, что такие ситуации для программ пока еще невозможны.[5]

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

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

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

Первым языком программирования, в котором были предложены основные понятия, впоследствии сложившиеся в парадигму, была Simula 67, модернизированная версия Simula I, языка программирования, ориентированного на дискретно-событийное моделирование. Язык предназначался для моделирования ситуаций реального мира. Особенностью Simula было то, что программа, написанная на языке, была организована по объектам программирования. Объекты имели инструкции, называемые методами, и данные, которые назывались переменными; методы и данные определяли поведение объекта. В процессе моделирования объект вел себя согласно своему стандартному поведению и, в случае необходимости, изменял данные для отражения влияния назначенного ему действия. Авторы Simula — Оле-Йохан Даль и Кристен Нюгорд из Норвежского компьютерного центра в Осло. Simula разрабатывалась под влиянием SIMSCRIPT и предложенной Чарльзом Хоаром концепцией записей-классов. Simula включала в себя понятие классов и экземпляров (или объектов), а также подклассов, виртуальных методов, сопрограмм и дискретно-событийное моделирование как часть собственной парадигмы программирования. В языке использовался автоматический сборщик мусора, который был изобретен ранее для функционального языка Lisp. Simula использовалась тогда преимущественно для физического моделирования.[7]

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

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

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

Тимоти Бадд пишет[8]:

«Роджер Кинг аргументированно настаивал, что его кот является объектно-ориентированным. Кроме прочих своих достоинств, кот демонстрирует характерное поведение, реагирует на сообщения, наделён унаследованными реакциями и управляет своим, вполне независимым, внутренним состоянием.» [ http://dl.acm.org/citation.cfm?id=66469&preflayout=flat]

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

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

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

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

Для языка высокого уровня первым шагом к повышению абстракции является использование функций, позволяющее после написания и отладки функции отвлечься от деталей ее реализации, поскольку для вызова функции требуется знать только ее интерфейс. Если глобальные переменные не используются, интерфейс полностью определяется заголовком функции.[9]

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

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

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

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

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

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

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

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

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

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

Основными свойствами ООП являются инкапсуляция, наследование и полиморфизм.[11]

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

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

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

Иерархия классов представляется в виде древовидной структуры, в которой более общие классы располагаются ближе к корню, а более специализированные — на ветвях и листьях. В С++ каждый класс может иметь сколько угодно потомков и предков. Иногда предки называются надклассами или суперклассами, а потомки — подклассами или субклассами.[12]

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

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

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

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

Глава 2. Критический взгляд на ООП

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

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

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

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

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

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

  • Было показано отсутствие значимой разницы в продуктивности разработки программного обеспечения между ООП и процедурным подходом[16].
  • Кристофер Дэйт указывает на невозможность сравнения ООП и других технологий во многом из-за отсутствия строгого и общепризнанного определения ООП [C. J. Date, Introduction to Database Systems, 6th-ed., Page 650].
  • Александр Степанов в одном из своих интервью указывал, что ООП «методологически неправильно» и что «…ООП практически такая же мистификация, как и искусственный интеллект…» [http://www.stlport.org/resources/StepanovUSA.html].
  • Фредерик Брукс указывает, что наиболее сложной частью создания программного обеспечения является «…спецификация, дизайн и тестирование концептуальных конструкций, а отнюдь не работа по выражению этих концептуальных конструкций…». ООП (наряду с такими технологиями как искусственный интеллект, верификация программ, автоматическое программирование, графическое программирование, экспертные системы и др.), по его мнению, не является «серебряной пулей», которая могла бы на порядок величины снизить сложность разработки программных систем. Согласно Бруксу, «…ООП позволяет сократить только привнесённую сложность в выражение дизайна. Дизайн остаётся сложным по своей природе…» [https://web.archive.org/web/20070315075634/http://inst.eecs.berkeley.edu/~maratb/readings/NoSilverBullet.html].
  • Эдсгер Дейкстра указывал: «…то, о чём общество в большинстве случаев просит — это эликсир от всех болезней. Естественно, „эликсир“ имеет очень впечатляющие названия, иначе будет очень трудно что-то продать: „Структурный анализ и Дизайн“, „Программная инженерия“, „Модели зрелости“, „Управляющие информационные системы“ (Management Information Systems), „Интегрированные среды поддержки проектов“, „Объектная ориентированность“, „Реинжиниринг бизнес-процессов“…» [http://www.cs.utexas.edu/users/EWD/transcriptions/EWD11xx/EWD1175.html].
  • Никлаус Вирт считает, что ООП — не более чем тривиальная надстройка над структурным программированием и преувеличение её значимости, выражающееся, в том числе, во включении в языки программирования всё новых модных «объектно-ориентированных» средств, вредит качеству разрабатываемого программного обеспечения.
  • Патрик Киллелиа в своей книге «Тюнинг веб-сервера» писал: «…ООП предоставляет вам множество способов замедлить работу ваших программ…».
  • Известная обзорная статья проблем современного ООП-программирования перечисляет некоторые типичные проблемы ООП [http://blogerator.ru/page/oop_why-objects-have-failed]
  • В программистском фольклоре получила широкое распространение критика объектно-ориентированного подхода в сравнении с функциональным подходом с использованием метафоры «Королевства Существительных» из эссе Стива Йегги [http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html].

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

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

Например, Пол Грэм говорит:

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

Хотя иногда объектно-ориентированный код действительно годится для повторного использования, таким его делает вовсе не объектно-ориентированность, а программирование в стиле „снизу вверх“. Возьмём, например, библиотеки: их можно подгружать и повторно использовать сколько угодно, потому что, по сути, они представляют собой отдельный язык. И при этом, совсем неважно, написаны ли они в объектно-ориентированном стиле или нет.»

Другой крупный критик ООП — это известный специалист по программированию — Александр Степанов, который работая в Bell Labs участвовал в создании C++ вместе c Бьерном Страуструпом, а впоследствии, уже по приглашению в HP Labs, написал Standard Template Library (STL).

Александр Александрович полностью разочаровался в парадигме ООП, в частности он пишет:

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

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

Ричард Столлман также известен своим критическим отношением к ООП, особенно он любит шутить насчет мифа объектников что ООП «ускоряет разработку программ»:

«Как только ты сказал слово „объект“, можешь сразу забыть о модульности»

«ООП ради самой ООП уже давно превратилось в замкнутый круг. Конечно, можно считать C# в .NET 3.5 с более чем 50,000 реализованных классов „венцом эволюции“. Добавить в следующей версии .NET ещё миллион классов — что может быть более правильным и более вожделенным, с точки зрения ООП-программиста? Говорите, это и есть то самое бегство от сложности?»

Java/C# не являются ни развитием, ни «осознанием ошибок» C++. Они взяли наихудшую парадигму из языка и возвели ее в степень настоящей догмы. А именно — идею наследования.

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

Томас Поток из MIT даже провел масштабное прикладное исследование [http://www.csm.ornl.gov/%7Ev8q/Homepage/Papers%20Old/spetep-%20printable.pdf], которое продемонстрировало, что нет никакой заметной разницы в производительности между программистами работающими в ООП и в обычном процедурном стиле программирования. «Это просто миф, который отлично работает вкупе с невежеством масс — если вы никогда не видели ничего кроме ООП, как же вообще вы можете в ней сомневаться?».

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

Ещё один ветеран программистского ремесла, Джоэл Спольски, рассказывает, что во время его работы в Microsoft его так достали тамошние адепты-инженеры ООП, что даже сейчас, по прошествии почти десяти лет, его передергивает от людей, «с головой погрязших» в этой парадигме. Джоел — автор популярного в англоязычной литературе шутливого термина Архитектурные Астронавты, который пошел гулять из его популярной статьи «Не дайте Астронавтам Архитектуры вас запугать» [http://www.gnuman.ru/joel/Ne_dajte_Astronavtam_Arhitektury_vas_zapugat/], посвященной именно тем самым архитекторам-инженерам из Microsoft, которые так упорно преследовали Джоела со своими абстрактными ООП-концепциями и шаблонами.

Ричард Гэбриел, позже, заново систематизировал, с учетом имевшего место широкого обсуждения и критики, после чего все было сведено в брошюру, которую Ричард выложил в свободный доступ [http://blogerator.org/go.php?url=http://www.dreamsongs.com/Files/ObjectsHaveFailed.pdf] вместе с поясняющими её слайдами [http://blogerator.org/go.php?url=http://www.dreamsongs.com/Files/ObjectsHaveFailedSlides.pdf].

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

Заключение

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

Список литературы

  • Thomas E. Potok, Mladen Vouk, Andy Rindos. Productivity Analysis of Object-Oriented Software Developed in a Commercial Environment (англ.) / — 1999. — Vol. 29, no. 10.
  • Бруно Бабэ. Просто и ясно о Borland C++: Версии 4.0 и 4.5 Пер. с англ. / Бабэ Бруно -М.: БИНОМ, 1994. - 400с.
  • Буч Г. «Объектно-ориентированный анализ и проектирование с примерами приложений на С++» Пер. с англ. / Г. Буч - М.: Бином; СПб.: Невский диалект, 1999.
  • Жуков А. «Изучаем С» / А. Жуков - СПб.: Питер, 2003.
  • Ишкова Э. «С++ начала программирования» / Э. Ишкова - М.: Бином, 2001.
  • Клочков Д.П., Павлов Д.А. Введение в объектно-ориентированное программирование. Учебно-методическое пособие. / Д.П. Клочков, Д.А. Павлов - Изд. Нижегор. ун-та, 1995. - 70с.
  • Мухортов В.В., Рылов В.Ю. Объектно-ориентированное программирование, анализ и дизайн (методическое пособие) / В.В. Мухортов, В.Ю. Рылов - ИМСО РАН, Новосибирск, 2002
  • Страуструп Б. Язык программирования С++ (2-ред). Пер. с англ. / Б. Страуструп -М.: Радио и связь, 1995. - 352с.
  • Шилдт Герберт. Самоучитель С++ (2-ред). Пер. с англ. / Герберт Шилдт - СПб.: BHV-Санкт-Петербург, 1997. -512с.
  • Элиас М., Страуструп Б. Справочное руководство по языку С++ с комментариями. Пер. с англ. / М. Элиас, Б. Страуструп - М.: Мир, 1992. -279с.
  1. Мухортов В.В., Рылов В.Ю. Объектно-ориентированное программирование, анализ и дизайн (методическое пособие) / В.В. Мухортов, В.Ю. Рылов - ИМСО РАН, Новосибирск, 2002, -15с.

  2. Элиас М., Страуструп Б. Справочное руководство по языку С++ с комментариями. Пер. с англ. / М. Элиас, Б. Страуструп - М.: Мир, 1992. -69с.

  3. Клочков Д.П., Павлов Д.А. Введение в объектно-ориентированное программирование. Учебно-методическое пособие. / Д.П. Клочков, Д.А. Павлов - Изд. Нижегор. ун-та, 1995. - 31с.

  4. Клочков Д.П., Павлов Д.А. Введение в объектно-ориентированное программирование. Учебно-методическое пособие. / Д.П. Клочков, Д.А. Павлов - Изд. Нижегор. ун-та, 1995. - 32с.

  5. Клочков Д.П., Павлов Д.А. Введение в объектно-ориентированное программирование. Учебно-методическое пособие. / Д.П. Клочков, Д.А. Павлов - Изд. Нижегор. ун-та, 1995. - 34с.

  6. Клочков Д.П., Павлов Д.А. Введение в объектно-ориентированное программирование. Учебно-методическое пособие. / Д.П. Клочков, Д.А. Павлов - Изд. Нижегор. ун-та, 1995. - 36с.

  7. Элиас М., Страуструп Б. Справочное руководство по языку С++ с комментариями. Пер. с англ. / М. Элиас, Б. Страуструп - М.: Мир, 1992. -54с.

  8. Тимоти Бадд. Объектно-ориентированное программирование в действии = An Introduction to Object-Oriented Programming. — СПб.: «Питер», 1997. — 253с.

  9. Элиас М., Страуструп Б. Справочное руководство по языку С++ с комментариями. Пер. с англ. / М. Элиас, Б. Страуструп - М.: Мир, 1992. -151с.

  10. Элиас М., Страуструп Б. Справочное руководство по языку С++ с комментариями. Пер. с англ. / М. Элиас, Б. Страуструп - М.: Мир, 1992. -152с.

  11. Буч Г. «Объектно-ориентированный анализ и проектирование с примерами приложений на С++» Пер. с англ. / Г. Буч - М.: Бином; СПб.: Невский диалект, 1999. -76с.

  12. Буч Г. «Объектно-ориентированный анализ и проектирование с примерами приложений на С++» Пер. с англ. / Г. Буч - М.: Бином; СПб.: Невский диалект, -112с..

  13. Бруно Бабэ. Просто и ясно о Borland C++: Версии 4.0 и 4.5 Пер. с англ. / Бабэ Бруно -М.: БИНОМ, 1994. - 245с.

  14. Буч Г. «Объектно-ориентированный анализ и проектирование с примерами приложений на С++» Пер. с англ. / Г. Буч — 2-е изд. - М.: Бином; СПб.: Невский диалект, 1999. — 276-278с.

  15. Буч Г. «Объектно-ориентированный анализ и проектирование с примерами приложений на С++» Пер. с англ. / Г. Буч — 2-е изд. - М.: Бином; СПб.: Невский диалект, 1999. —280.

  16. Thomas E. Potok, Mladen Vouk, Andy Rindos. Productivity Analysis of Object-Oriented Software Developed in a Commercial Environment (англ.) // Software – Practice and Experience. — 1999. — Vol. 29, no. 10. — P. 833—847.