информационная безопасность
без паники и всерьез
 подробно о проекте
Rambler's Top100Где водятся OGRыПортрет посетителя
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Logitech готовится закрыть очередную... 
 Серьёзная атака на инфраструктуру... 
 Microsoft призналась в сознательном... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / библиотека / программирование
БИБЛИОТЕКА
вход в библиотеку
книги
безопасность
программирование
криптография
internals
www
телефония
underground
беллетристика
разное
обзор: избранное
конкурс
рейтинг статей
обсуждение




Подписка:
BuqTraq: Обзор
RSN
БСК
Закон есть закон




Теология ООП
Овик Меликян
Опубликовано: dl, 13.11.04 23:18

В последние годы появились весьма неочевидные прогнозы, и даже чуть ли не констатация факта о провале объектной парадигмы, ООП. Крайнюю позицию высказал Ричард Гейбриэл в своем выступлении на OOPSLA под прямым названием "Объектная парадигма провалилась". Другой, более сдержанный и взвешанный прогноз - это Пол Грэм со своей статьей "Языки программирования через сто лет".

Объединяет этих двух людей то, что они приверженцы функционального программирования и языка Lisp. "А, да это брюзгливые математики, для которых высочайшим достижением программирования является интерпретатор языка Lisp на языке Lisp в 20 строк" - так бы я отреагировал на эти статьи годами раньше. Но в статье Ричарда Гейбриэла есть слишком много правды, и в ответах оппонентов (например здесь) слишком мало рационального, чтобы можно было не задумываясь пройти мимо этой дискуссии.

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

 

***

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

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

Во-вторых. Эти школьные примеры с GUI объектами на самом-то деле и есть область применения ООП. В мире реального программирования многое можно, а иногда даже нужно, делать без этого. Зачастую описывая классы мы даже не задумываемся над тем, а будут ли объекты данного класса persistent настолько, что следует вводить понятие состояния объекта, и тем самым усложнять его реализацию. Какая-то группа данных, т.е. структура, действительно может иметь состояния если того пожелать, но тогда каждая точка входа в эту структуру, т.е. методы объекта, должны прежде сверяться с состоянием и затем только выполнять какие-то действия. Мы просто-напросто усложняем наши программы вводя состояния и сверки там, где в этом не было острой необходимости. Пол Грэм в одной из своих статей писал, что если возможно реализовать что-то в виде обычной функции с самыми обычными параметрами, то следует делать именно так, поскольку функция изолируется и следовательно отлаживается гораздо лучше метода объекта.

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

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

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

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

 

***

Еще в 1998-ом году, когда я начал писать свою кустарную альтернативу STL, как вероятно когда-нибудь делали все Си++ программисты, я не смог бы изложить все свои претензии к ООП так пространно, но уже интуитивно осознавал где есть перебор с объектами. Позже моя кустарщина переросла в open-source проект под названием PTypes.

Тогда, понимая, что не все должно иметь ОО интерфейсы, я решил экспериментально описать алгебраические интерфейсы там, где нет наследования и полиморфизма. Замечу, что внутри все по-прежнему реализовано в классах, поскольку требовалось, например, перегрузить оператор + для строк, а вне класса в Си++ такое сделать невозможно. Строка - это атомарный (в смысле фундаментальный) тип, от которого врядли имеет смысл производить классы с перегруженными виртуальными методами, так же как и от простого int. Следовательно, интерфейс строки для пользователя может быть алгебраическим: такую простую вещь как length(s) никто не отменял и никто не сказал, что это обязательно должно записываться как s.length().

Точно так же я рассуждал и в отношении списков, и фактически удалось даже привести интерфейсы списков и строк в некотрое соответствие. Например length() был одинаково применим и ко всем типам списков. Делалось это для того, чтобы не загружать пользователя лишними понятиями. Length(), setlength() и некоторые другие методы универсальны насколько это возможно. Позже появился еще и variant, и тоже с алгебраическим интерфейсом.

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

Далее я даже умудрился описать шаблоны списков для произвольных базовых типов, сохраняя при этом алгебраические вызовы. Все бы ничего, только со временем я начал получать письма от пользователей с такими жалобами. Они в принципе не против самой идеи, но дело в том, что после усложнения библиотеки компиляторы стали путаться с большим количеством перегруженных функций (не методов!), описанных в шаблонах. Это были на самом-то деле баги в самих компиляторах (причем баги были разные, например у MSVC и GCC). Тут я понял, что такие фокусы с Си++ мало кто вытворяет, и поэтому ошибки в компиляторах остаются незамеченными. Я пытался давать баг-репорты создателям компиляторов, но ими никто не занимался наверное из-за слишком экзотического применения перегрузок обычных функций в купе с шаблонами.

Словом, в версии 2.0 библиотеки я вынужденно переписал списки и сделал их чисто-объектными. Ничего страшного, но теперь к сожалению length() уже не применим к спискам, и первоначальная идея библиотеки малость пострадала. К счастью, она по-прежнему популярна, особенно среди новичков, потому что она, кроме всего прочего, позволяет очень быстро запрыгнуть на корабль сетевого и многопоточного программирования и писать очень простой и главное - ясный, читабельный код на Си++.

 

***

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

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

 

Ваше мнение?

 

К читателю. Честно говоря я немного разочарован из-за оставляемых в моем блокноте комментариев типа "в Джаве это давно сделано", или "да Вы идиот, подите почитайте то-то". Нужны рациональные ответы по существу, понимаете? Я мог бы не стирать такие записи следуя принципам демократичности Интернета вообще, но просто другие будут тратить свое время, если повсюду будут мельтешить эти ничего не значащие реплики. Мне действительно жаль, что пришлось что-то стирать, потому что поначалу я не собирался этого делать.

Буду рад всякому оппоненту, который сможет раздолбать мои статьи по пунктам. Но даже как-то неудобно просить вас говорить по существу, ведь это вообще-то само собой разумеющаяся вещь!



Оригинал: http://www.melikyan.com/dalshe/articles/oop.html

обсудить  |  все отзывы (7)  

[22229; 18; 5.5]




Rambler's Top100
Рейтинг@Mail.ru





  Copyright © 2001-2019 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach