Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Онлайн-курс по SQL для новичков.
Теория, практика, поддержка, сертификат.

Почему объектно-ориентированное программирование провалилось?

Прошло ровно 10 лет со времени публикации известной и классической в мире программирования статьи, написанной Ричардом Гэбриелом (Richard Gabriel), название которой стало уже нарицательным и вынесено в заголовок моей статьи. Статья стала настолько острой и злободневной для своего времени, что вызвала бурный всплеск обсуждений в сообществе программистов, целый ряд известных программистов включился в открытую полемику с автором, от редакции известнейшего американского программистского журнала Dr. Dobb’s Journal до таких ученых как Эндрю Таненбаум (Andrew Tanenbaum).

Автор этой нашумевшей статьи, доктор компьютерных наук Стэнфорда, старший архитектор по разработке ПО сначала Sun, а потом и IBM, Ричард Гэбриел никогда не скрывал своего скептического отношения к парадигме ООП. В 2002 году, по прошествии 2 лет после первоначальной публикации своей критической статьи автора пригласили выступить, теперь уже живьем и перед большой аудиторией, – и изложить свои критические взгляды на ежегодной конференции OOPSLA (центральная конференция IT-специалистов по объектно-ориентированным языкам и методологиям разработки ПО). И, чтобы по старой доброй американской традиции превратить это в горячее шоу, в качестве его оппонента одновременно пригласили Гая Стила (Guy Steele) , отца-разработчика языка Scheme, крупнейшего специалиста-теоретика по ООП, авторитет которого в американской академической среде непререкаем.

Чтобы максимально отразить позиции выступающих, их решили усилить ещё двумя выступающими. В качестве “анти-объектника” дополнительно пригласили Пола Грэма (Paul Graham) , крупнейшего специалиста по Lisp, автора многочисленных книг и стандартизаций Lisp, кстати, согласно Википедии, в 1995 году создавшего вместе с Робертом Моррисом первое в мире web-приложение – Viaweb, которое затем выкупила у них Yahoo (как мы все знаем, Роберт Моррис (Robert Morris), близкий друг и коллега Пола, на этом достижении не остановился, и написал, пожалуй, самый знаменитый червь в истории интернета, но это уже совсем другая история). В стан объектников пригласили Джеймса Ноубла (James Noble), автора одних из первых книг и работ по теории ООП. Многие участники вспоминают, что конференция этого года надолго запомнилась им по тому уровню обсуждения, которое завязалось тогда в этой публичной “интеллектуальной дуэли” фактически диаметрально разных школ программирования.

Но факт остаётся фактом: сторона, представлявшая объектно-ориентированное программирование, во время открытой дискуссии с противниками под смех зала даже запуталась в своих же концепциях. Люди вспоминают, что у всех создалось стойкое впечатление, что аргументация Lisp’еров была куда убедительней и последовательней, чем сторонников ООП (любопытно, что главным докладчиком по ООП был создатель языка Scheme – главного современного диалекта того же Lisp’а).

Пол Грэм утверждал, что половина всех концепций ООП являются скорее плохими, чем хорошими, в связи с чем он искренне сочувствует ООП-программистам, тогда как вторая половина от оставшихся концепций и вовсе не имеет никакого отношения к ООП, с которыми их почему-то постоянно ассоциируют. Например, он говорит: “В восьмидесятых годах метод повторного использования каким-то неясным мне образом связали с объектно-ориентированным программированием, и сколь угодно многочисленные имеющиеся доказательства обратного, по-видимому, уже не избавят этот метод от клейма ООП. Хотя иногда объектно-ориентированный код годится для повторного использования, таким его делает вовсе не объектно-ориентированность, а программирование в стиле "снизу-вверх". Возьмём, например, библиотеки: их можно подгружать и повторно использовать сколько угодно, потому что, по сути, они представляют собой отдельный язык. И при этом совсем неважно, написаны ли они в объектно-ориентированном стиле или нет.”

Другой крупный критик ООП – это известный специалист по программированию Александр Степанов, который, работая в Bell Labs, участвовал в создании C++ вместе c Бьерном Страуструпом (Bjarne Stroustrup), а впоследствии, уже после приглашения в HP Labs, написал Standard Template Library (STL). Александр Александрович полностью разочаровался в парадигме ООП; в частности, он пишет: “Я уверен, что парадигма ООП методологически неверна. Она начинает с построения классов. Это как если бы математики начинали бы с аксиом. Но реально никто не начинает с аксиом, все начинают с доказательств. Только когда найден набор подходящих доказательств, только тогда на этой основе выводится аксиома. Т.е. в математике вы заканчиваете аксиомой. Тоже самое и с программированием: сначала вы должны начинать развивать алгоритмы, и только в конце этой работы вы приходите к тому, что оказываетесь в состоянии сформулировать четкие и непротиворечивые интерфейсы. Именно из-за этой неразберихи в ООП так популярен рефакторинг – из-за ущербности парадигмы вы просто обречены на переписывание программы, уже в тот самый момент, когда только задумали её спроектировать в ООП-стиле”. Ричард Столлман (Richard Stallman) также известен своим критическим отношением к ООП, особенно он любит шутить насчет того мифа объектников, что ООП “ускоряет разработку программ”: “Как только ты сказал слово "объект", можешь сразу забыть о модульности”.

Томас Поток (Thomas Potok) из Oak Ridge National Laboratory даже провел масштабное прикладное исследование, которое продемонстрировало, что нет никакой заметной разницы в производительности между программистами, работающими в стиле ООП и в обычном процедурном стиле программирования.

Почти все пункты своего выступления и претензии к ООП как к парадигме Ричард Гэбриел позже заново систематизировал с учетом имевшего место широкого обсуждения и критики, после чего все было сведено в брошюру, которую Ричард выложил в свободный доступ вместе с поясняющими ее слайдами (очень краткое содержание его выступления можно найти и в переводе на русский язык). После этого очень сильного выступления у него появилось много последователей, которые попытались систематизировать все мифы и дефекты ООП в своих многочисленных статьях и работах. К сожалению, вероятно, из-за того, что как я уже сказал выше, ответное выступление объектников “Почему ООП не провалилось” получилось несколько скомканным из-за интеллектуального натиска Lisp’еров; выступавшие так и не оформили впоследствии свою позицию преимуществ ООП в развернутом виде. В интернете сохранилось лишь краткое содержание-конспект их выступления, которое также существует как в английской оригинальной версии, так и в русском переводе.

Ричард Гэбриел неожиданно сравнивает нынешнюю ситуацию с ООП с провалом эфиродинамики в физике начала 20 века, когда, в сущности, произошла “тихая революция”. Молодые сторонники теории относительности, массово пришедшие в номенклатуру университетов, тогда постепенно захватили власть в области преподавания физики, навязав свою, столь любимую интеллектуалами того времени, теорию относительности широким массам физиков. На самом деле, в то время имелись как положительные эксперименты и опыты, подтверждавшие существование эфира, так и отрицательные. Первые были полностью проигнорированы и исключены административными мерами из всех учебников физики, после чего эфир был незаслуженно “закрыт” и отправлен в отставку, и вот уже нынешнее поколение студентов-физиков даже и не знает о тех весьма успешных опытах по обнаружению эфирного ветра. “Ну и где мы теперь, с этой вашей красивой теорией относительности, кто-нибудь может мне назвать хоть какие-то реально-практические результаты её применения в вашей обыденной жизни после целого века её ковыряния и массового насаждения?” – как всегда язвительно вопрошает Гэбриел.

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

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

Blogerator.ru

Комментарии

Страницы комментариев: предыдущая :: 1 :: 2 :: 3 :: 4 :: 5 :: ... :: 149 :: следующая

аноним, Вс 05 янв 2014 00:56:07:
тсс... он рядом
аноним, Вс 05 янв 2014 00:34:02:
нытик с рюмкой рома нам не товарищ
аноним, Вс 05 янв 2014 00:06:17:
Только бы не пришел сюда чудик-нытик с рюмкой рома из соседней темы, вообразивший себя пупом Земли после посещения Йемена.) Он бы всех вас научил уму-разуму!)
Кстати, только что забавная мысль в голову пришла. Ведь тот единственный в жизни раз, когда я по своей инициативе использовал ООП, я фактически решал ту же самую задачу, под которую С++ и создавался ! Если кто забыл, создавался он именно для задач МОДЕЛИРОВАНИЯ вместо тормозной Симулы-67. Ну так и я использовал его именно для моделирования. Не телефонной сети правда, а конвейерного алгоритма, но какая разница... Не удивительно что в тот раз поимел от С++ кучу положительных эмоций ибо просто употребил инструмент по назначению. Но когда некто утверждает, что этот инструмент хорош вообще на все случаи жизни, это не меньший маразм, чем имея молоток (да очень классный молоток !), утверждать что этот инструмент универсален и пытаться пилить им дрова.
Беларус, Сб 04 янв 2014 23:47:29:
К ООП тоже отношусь спокойно, отрицательно.

Так вот, написание кода - это мелочи. Это 5-10% времени и стоимости разработки. Сотни миллиарды долларов и миллионы человеко-лет (без преувеличения), как в трубу, вылетают на поддержание (тестирование, правку багов) софта. Вот это и есть настоящая проблема. Да еще программисты наповадились с места на место бегать каждые 2-4 года, -- только человек освоится и годик поработает продуктивно, -- глядишь, он уже опять куда-то намыливается... И вот тут возникает интересная проблема. В связи с высокой текучестью кадров и большой сложностью реальных проектов читаемость и модифицируемость кода приобретает первостепенное значение!

Чтобы код был читаем и легко модифицируем, крайне желательно, чтобы он был локально понятен. Так, чтобы новый человек, посмотрев на процедуру, смог достаточно быстро понять, что она делает и как. И вот тут, в объектно-ориентированных языках типа Java, С# начинается веселье с конструкторами, деструкторами, виртуальными функциями, наследованием, монстроидальным шаблонным метапрограммированием, полиморфизмом, исключительными ситуациями... Увидев вызов простой функции, как правило сразу понятно что происходит, можно сходить и посмотреть, что она делает. В объектно ориентированных языках, где народ (в особенности вчерашние студенты) любят, ой как любят переоперделять функции, не поймешь, какой из 15 виртуальных методов будет вызван в данном контексте, и читать текст их всех дело утомительное. В результате починка бага занимает в 3-5 раз больше времени.

Перейдем к деструкторам и конструкторам. Видит программист описание локальной переменной, которая нигде не используется, и, не сомневаясь, удаляет его. Программа перестает работать. Что случилось? Оказывается, конструктор этой переменной устанавливает связь с другим объектом. Конечно, за такие фокусы (я имею в виду создание такого конструктора) нужно увольнять, но что написано пером - не вырубишь топором. В результате программист (по-хорошему) вынужден прочитать описания всех конструкторов и деструкторов по всей цепочке наследования всех локальных cтруктурных переменных процедуры. Кому хочется шариться по 40 файлам, чтобы понять, что делается в процедуре? — да никому. Никто этого и не делает, в результате через 3 года в программе, лихо написанной на объектно ориентированном языке, не разберется никто. Посему, и надежность программ, размашисто написанных на таких языках, оставляет желать лучшего. Я уже не говорю про перекрытие операторов, конструкторов копирования и прочее. Творческое пользование темплейтами также сможет доставить потомкам немало приятных минут. А чего стоят исключительные события? Почему-то получается, что код, написанный на языке программирования без скрытого поведения, поддерживать и сопровождать гораздо легче. Просто уже потому, что вероятность наступить на грабли меньше. Описана переменная -- можно быть уверенным, что ничего больше это не означает. Вышли из блока -- значит, вышли, и нечего кроме. Что написано, то и происходит. Когда же приходится докапываться до третьего слоя истины -- это бардак. К сожалению, на объектно ориентированных языках наломать дров проще простого, что мы и наблюдаем изо дня в день.

Как это ни удивительно, при промышленном программировании залогом хорошего здоровья является простота. Чем проще, тем лучше. Код должен быть понятен, иначе человек, который заменит Вас через 2-4 года, не справится. Хотите проинициализировать переменную? Вызовите процедуру. Надо вызвать функцию? Вызовите ее напрямую. Очевидно, что чем проще язык программирования, тем трудней сделать на нем семантическую ошибку. Если достаточно полное и предельно краткое описание языка занимает около 1000 страниц, можно ли ожидать, что рядовой программист будет знаком хотя бы с 50% особенностей языка? -- навряд ли. Тогда откуда может быть уверенность, что достаточно навороченная конструкция представляет собой именно то, что хотел сказать программист?

Далее. Стандартные библиотеки. Опять же, с точки зрения промышленного программирования, — чем проще, тем лучше. Если в стандартной библиотеке (к тому же динамически подгружаемоей) есть баг, то это беда. Если программисты его не нашли -- значит, найдут пользователи. Если нашли и обошли, то проблемы начнутся после того, как пользователь обновит библиотеки и в новой версии баг будет починен. Наконец, необходимым требованием является 100% обратная совместимость библиотек. Ну скажите мне, хоть одна библиотека для Java удовлетворяет этому требованию? А есть ли там хоть одна процедура без какого-либо ляпа? Я уже не говорю о вопросах совместимости, инсталляции и прожорливости разных версий фреймворков под C# .NET и о том, что на изучение постоянно изменяющихся спецификаций различных новомодных библиотек может уйти полжизни, не говоря уже о проблемах стабильности их работы на практике.

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

Вообще, за последние 20 лет вышла масса литературы на тему дизайна программного обеспечения. Авторы книг статей постарались на славу. Были выделены и формализованы основные конструкции в виде паттернов проектирования. Сформированы основные практики и рекомендации. Однако, у этой большой и красивой медали есть обратная сторона – очень редко говорится О РЕАЛЬНОЙ НЕОБХОДИМОСТИ ПРИМЕНЕНИЯ тех или иных методик, а также о трудозатратах при этом. Подавлющая масса молодых программистов из-за отсутсвия опыта воспринимает все подобные материалы совершенно неадекватно, стремясь де-факто реализовать в одном месте практически все то, о чем они когда-либо читали и слышали (а слышали они в силу возраста как раз все последние веяния). Им трудно дифференцировать рациональные зерна от бесполезных "бантиков" и программирование превращается не столько в создание требуемого функционала, сколько в продумывание деталей как это будет написано. Внешнее и второстепенное выдвигается на первое место. Значительную часть времени начинает занимать бесполезный рефакторинг программного текста и мысли о том как же организовать очередное хитрое зацепление классов, в то время как создание полезнго функционала уходит на задний план. Например, в игровой индустрии подобные повадки особенно вредны. Нужен функционал, не нужен лишний текст. 99% текста выполняют 100% работы.

Например, когда-то одному разработчику был дан проект очень незатейливой игры. Предполагалось, что эта игра займет около месяца разработки. Но месяца не хватило. Спустя шесть недель выяснилась причина. Программист попался очень педантичный и вместо того чтобы взять чистый СИ и написать игру, он 80% времени занимался тусовкой классов в сложнейшей иерархии. Когда посчитали – оказалось порядка 210 классов. Движок получился, была написана чудовищная гора текста. В объекты было завернуто все, начиная от объектов межпоточной синхронизации и кончая экранными виджетами со своей собственной системой сообщений. Да только вот беда — сама игра была в совершенно зачаточном состоянии и не работала. Старые игры для GBA, C64, NES, SNES, Megadrive, ZX Spectrum, Atari, N64 всегда, с неизменным постоянством работали как часики. Можно конечно сейчас сказать "ну знаешь ли, не сравнивай сложность продуктов". А ничего подобного! Просто нужно знать как писались эти вещи и на чем писались. Раньше ведь даже не было IDE, и дебаггеров с одним тычком мыши. Не было самих мышей. Загружались с дискет (а еще раньше с кассет!). Иногда не было возможности отлаживаться или даже запускать код на самом устройстве. Так может уделять внимание эффективности, задачам которые пытаемся сделать?

Информация к размышлению: http://www.softpanorama.org/SE/anti_oo.shtml
SAABeilin, Сб 04 янв 2014 23:43:32:
Во-первых, спасибо за интересный материал!

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

И отдельное спасибо Clr :)

Сергей.
Владимир, Сб 04 янв 2014 23:28:51:
Огромные проекты пишут и на Plain C. Естественно, что в нужных местах используются методики ООП.

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

Вот и программисты на Plain C тоже пользуются ООП. Вместо

class foo

{

int number;

bool set_number(int n);

};

они напишут:

struct foo

{

int number;

bool (*set_number)(struct *foo, int n);

};

И вместо наследования и полиморфизма будут применять присвоение указателей на разные функции. Инкапсуляция на Plain C тоже в большинстве случаев получается лучше. Например, в h-файле можно объявить несколько функций, принимающих безтиповый указатель, а в c-файле этот безтиповый указатель внутри функции будет приводиться к указателю на структуру определённого типа. В результате из h-файла вообще будет невозможно узнать о том, что там есть внутри этой структуры. В то же время в C++ все потроха наверняка класса придётся объявлять в h-файле, что будет способствовать использованию программистом-пользователем класса его внутренних особенностей, что в корне подрывает саму идею инкапсуляции.

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

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

Кстати, ООП в C++ - это скорее пример того, как можно хорошую идею испортить плохой реализацией. Даже в Object Pascal ООП лучше, поскольку позволяет достичь большего сокрытия внутренних деталей реализации объекта. Но и Object Pascal - не идеал, т.к. не поддерживает идею ОБМЕНА СООБЩЕНИЯМИ между объектами. Весь обмен сообщениями сводится к вызову методов, что подразумевает, например, невозможность отправки асинхронных сообщений средствами самого языка. Невозможно средствами языка адаптировать интерфейсы разных объектов друг к другу (банально - переставить аргументы между собой при выполнении вызова метода или передачи сообщения, ориентируясь на типы и имена этих аргументов) и т.п. То есть при ведении дискуссии "ООП против другой парадигмы" нужно учитывать ещё и то, какой конкретно ООП имеется в виду: ООП в стиле Object Pascal, в стиле C++, в стиле Smalltalk или Objective-C. Вердикт будет зависеть от типа ООП и задачи, которую требуется решить с его помощью.
Clr, Сб 21 сен 2013 23:46:06:
Конечно, есть годные ООП языки, такие как Руби, Питон... Реально хорошие и мощные языки, позволяющие прямо сказать машине, что нужно сделать, не ***хая мозг созданием нового класса на каждый чих. Но эти языки хороши не потому, что они ООП, а потому что это динамические рефлективные высокоуровневые языки. (Хых, для кого я это пишу... Из всех, кто тут писал комментарии, слово рефлективный поймёт 3 с половиной человека, не больше.)
Фактически, Руби и Питон - это Лисп с человеческим лицом. "Лисп для бедных." А все языки по своей внутренней сути, как известно, сводятся либо к ассемблеру, либо к Лиспу — третьего не дано. А если кто-то пытается усидеть на двух стульях сразу, в итоге получается получается С++, templates (тьюринг-полный язык в языке, адская жесть), бинарники HellowWorld на 4 мегабайта, и рефакторинг, рефакторинг, рефакторинг...
аноним, Сб 21 сен 2013 22:19:23:
>Лично я обязуюсь регулярно перечислять 20%... нет, 22% нечестно полученных средств в "Фонд Гениальных Программистов"

Дружок, не надо лукавить. Членом "Фонда Гениальных Программистов" ты считаешь себя.
Никаких возражений нет - считай, перечисляй, можешь даже назначить себя Царем мирового кодинга. Причуды вашего круга интересны только вашему мирку.
win8pro+sg note2, Пт 20 сен 2013 18:44:48:
Не трожьте оопщников! Пусть убеждают себя в нужности. Им так легче.
аноним, Пт 20 сен 2013 16:24:15:
>Очевидно, что все мы ООПщники бесталанные халтурщики, слабаки, пародия на настоящих программистов.

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

Страницы комментариев: предыдущая :: 1 :: 2 :: 3 :: 4 :: 5 :: ... :: 149 :: следующая

Ваш комментарий

Имя:

Текст комментария (HTML-теги не допускаются):

Новости мира IT:

Архив новостей

Последние комментарии:

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...