об "объектной парадигме"

Читая как некоторые обитатели рассуждают об «объектной парадигме» пришел к печальному выводу, что «сумма разума на Земле — величина постоянная, а население растет...». Тем не менее, попытаюсь «на пальцах» рассказать, что, как это часто случается, дьявол кроется в мелочах и под крышей «объектной парадигмы» собраны весьма и весьма разные подходы к созданию програмного обеспечения. Настолько разные, что, зачастую, их объединяет только частично похожая терминология.

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

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

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

— Метапрограммирование или, по другому, шаблоны. Частично эту идею можно было встретить еще в PL/I, затем она была доведена до логического завершения в CLU, а затем совершенно извращенным способом трансформировалась в шаблоны в С++. Строго говоря, эта идея не является объектной, поскольку из тройки «инкапсуляция/наследование/полиморфизм» в ней отсуствует наследование. Тем не менее, этот подход (вполне заслуженно, кстати) нашел весьма широкое распространение именно в языках которые принято считать объектными. Видимо потому, что, на самом деле, наследование далеко не самая нужная (в реальной жизни, а не на бумаге) часть в объектно-ориентированном программировании.

— Duck typing, «ходит как утка, говорит как утка, значит это утка». Идея отчасти напоминает симулу, но вместо строгой проверки наследования используется подход больше напоминающий шаблоны С++ — объект считается реализующим конкретный интерфейс, если имеет все нужные сигнатуры методов. Наследование используется больше для удобства записи, а не для проверки типов. Из известных мне реализаций — Google Go.

— Наследование основанное на прототипах. JavaScript и его производные. Идея тоже довольно проста. Любой объект можно взять за основу (прототип) и добавив/изменив в нем поля/методы сделать новый объект. Можно ничего не менять, будут объекты одного типа (что, впрочем, в JavaScript никакой особой роли не играет). Наличие в JavaScript заметного количества функциональщины в комбинации с отсутствием проверки типов и специфической «средой обитания» отягощенной войной браузеров превращает его в весьма своеобразный инструмент.

— Наследование интерфейсов. На первый взгляд он кажется очень похожим на «С с классами», но возможность «заимплементить интерфейс» делает его здорово похожим на duck typing (хотя тут все делается явно и решение принимает программист, а не компилятор). Парочка самых известных реализаций этого подхода — Java и С#. Такой подход оказался весьма удобен (гораздо удобнее, чем плюсовый) для создания компонентов и компонентного программирования.
На практике именно компонентное программирование стало тем, что футурологи от программирования предсказывали как будущее плюсов. Отсутствие привязок к иерархии классов и простота интеграции готового кода породила просто чудовищное количество библиотек к Java (подозреваю и к C#).

Наверняка приведенный список не полон и существует множество других подходов. Тем не менее, даже беглый взгляд на них должен настораживать — слишком уж разные подходы собрались под крышей «объектной парадигмы». Подозрения вполне обоснованы. Одна и та же программа правильно спроектированная и написанная на одном «объектном» языке может не иметь ничего общего (кроме отсылок к предметной области) с не менее правильно спроектированной и написанной программой на другом «объектном» языке. Например, два внешне весьма похожих языка — С++ и Java. Программа на С++, скорее всего, будет содержать одну или несколько иерархий классов отражающих предметную область и все это будет сдобрено шаблонами (преимущественно для реализации стандартных алгоритмов и структур данных). Типичный такой объектный подход для «С с классами». Программа на Java будет состоять, скорее всего, из набора интерфейсов (в подавляющем большинстве случаев — без какой-либо иерархии) и набора реализаций этих интерфейсов (причем реализации, в лучшем случае, используют наследование только для выноса общего кода, то есть это чисто техническая подробность реализации, к предметной области никакого отношения не имеющая). С не меньшей долей вероятности этот «суп» из интерфейсов и классов будет собираться в работающую программу силами какого-нибудь DI (dependency injection) фреймворка и жить в каком нибудь контейнере (JEE, Spring или OSGi, возможны комбинации и вариации). Эти две программы будет объединять только то, что они реализуют одинаковую функциональность в конкретной предметной области. Все остальные идеи и подходы кардинально разнятся. Людей, приходящих из плюсов в жабу еще долго приходится переучивать, что бы они стали писать так, как это оптимально для данного инструмента.

Как не сложно заметить, все это как-то с трудом укладывается в определение парадигмы программирования. И отсюда же непосредственно следует, что рассуждения об, якобы, общности всех «С с классами» это, мягко говоря, демонстрация полного незнания предмета обсуждения.
  • +1
  • 24 ноября 2012, 00:45
  • evsi

Комментарии (21)

RSS свернуть / развернуть
На вентилятор бросили какашку.

Если уж хочешь действительно поговорить на тему объектов, то тебе нужно на msdn. А здесь получишь только холивар.
0
  • avatar
  • a9d
  • 24 ноября 2012, 01:51
А здесь получишь только холивар.
Как будто evsi что-то имеет против холивара. Еще и с охотой поучаствует.
0
msdn идет в сад.
0
Честно говоря, затрудняюсь понять к чему ты клонишь и в чей огород сей камень.
Метапрограммирование или, по другому, шаблоны.
Ну, это я бы вообще не стал относить к ООП. Метапрограммирование есть и в не-объектных языках, а сами шаблоны применимы и к функциям, без всякого ООП. В принципе, какое-никакое метапрограммирование есть и в С — препроцессор.
Ну и шаблоны — это не только метапрограммирование, но и обобщенное программирование. В ту же Delphi оно таки пришло, но только в ипостаси обобщенного программирования.
Наследование интерфейсов.
Ну, в Delphi в какой-то мере это есть. Но обычно не используется, ибо не в ее духе, да и эффективность оставляет желать лучшего. Да и впилено было в основном для поддержки COM.
0
  • avatar
  • Vga
  • 24 ноября 2012, 02:07
Ну, это я бы вообще не стал относить к ООП. Метапрограммирование есть и в не-объектных языках, а сами шаблоны применимы и к функциям, без всякого ООП. В принципе, какое-никакое метапрограммирование есть и в С — препроцессор.
Все верно, я об этом и написал. Просто есть много общего, например, с прототипами. Да и массовое применение началось именно с появлением в С++ шаблонов, хотя более неудобного в этом смысле инструмента еще поискать.
0
Гм, по моему в том же ЛИСПе метапрограммирование применялось задолго до того, как С++ вообще придумали.
0
Угу. И еще много где. Вот только лисп никогда не был массовым языком промышленного программирования.
0
Ну, если смотреть с этой точки зрения — С++ был первым массовым промышленным языком с метапрограммированием (хотя, тут я не уверен — не настолько знаю историю промышленных языков).
0
Из того, что более-менее широко применялось, я могу вспомнить только PL/I, но он почил в бозе еще до массового распространения персоналок разного пошиба, а именно они превратили программирование в массовую профессию, а применение компьютеров в массовое и повсеместное явление.

P.S. забавно, но нишу С на писюках вполне мог занять паскаль. для этого были все предпосылки, а в винде до 95-й в качестве соглашения о вызовах использовалось паскалевское и злые языки поговаривали, что первые версии были написаны на паскале, только тот никогда не поступал в продажу. у эплов была та же фигня, насколько я в курсе. и популярность турбопаскаля тоже была весьма высока. впрочем, это лишь мое предположение, которое больше базируется на слухах и догадках, чем на фактах.
0
хотя более неудобного в этом смысле инструмента еще поискать
а в чем неудобность?
0
Не буду ходить далеко за примерами, возьму весьма популярный прием, такой как трейты. Сам автор подхода пишет, что это if/then/else для шаблонов. О каком удобстве может идти речь, если такие елементарные вещи надо, по сути, лепить на коленке?
0
Наверное вы правы. И возможно механизмам проверки в шаблонах не хватает красоты «золотого сечения», но жить, как говориться можно.
Однако пофилософствуем немного. Поскольку предмет диспута логико — лингвистический инструментарий, то зададимся вопросом, а что же есть инструмент, в природе вещей? Очевидно, что инструмент, есть производное человеческой эволюции, и идею порождает проблема, необходимость ее решить. Проблема трансформируется, изменяется и инструментарий. Т.о. появление того или иного инструмента неразрывно связано с задачей, проблемой, его породившей.
Не находите ли вы, что упустили этот важный аспект? И каждый язык хорош и оптимален, в нише своей применяемости? Да, есть конкуренты, делящие место под солнцем. Но как известно природа не терпит рудиментов, и живучесть существующих экземпляров, разве не доказывает их состоятельности?
И не находите ли вы, что переучивать людей «приходящих из плюсов в жабу» не совсем рациональная задача? Ведь владея ложкой, вилкой и что совсем превосходно, ножом, вы будете уверенно чувствовать себя в любой компании.
0
Не находите ли вы, что упустили этот важный аспект?
Нет, не нахожу. Многие языки являются выражением взглядов на мир их авторов. К С++ это применимо едва ли не больше, чем ко многим другим языкам. В итоге практическая целесообразность была пожертвована в угоду академическим представлением автора о чистоте и правильности языка.
И не находите ли вы, что переучивать людей «приходящих из плюсов в жабу» не совсем рациональная задача?
С волками жить — по волчьи выть. Нельзя на плюсах писать как на жабе, а на жабе — как на плюсах. Это не целесообразно с любой точки зрения — рационального использования возможностей языка, эффективности получаемого кода, тестируемости, читаемости, сопровождаемости и так далее. Поскольку не я звал этих людей переходить на жабу, а они сами приняли такое решение, то они должны приспособиться или уйти обратно. Иначе то, что они пишут будет обходиться дороже, чем должно. А это, при всей моей любви к программированию, все-таки бизнес.
0
Читая как некоторые обитатели рассуждают об «объектной парадигме» пришел к печальному выводу, что «сумма разума на Земле — величина постоянная, а население растет...». Тем не менее, попытаюсь «на пальцах» рассказать …

Уж слишком резкое заявление. И я тоже затрудняюсь понять:

к чему ты клонишь и в чей огород сей камень.
0
Мне казалось, что намек на конкретного персонажа вполне прозрачен.
0
Проблемы с любыми языками программирования начинаются, когда обезьян подпускают к клавиатуре.
0
разве речь о проблемах?
0
Ув. evsi, Вы пишите
Метапрограммирование или, по другому, шаблоны. Частично эту идею можно было встретить еще в PL/I, затем она была доведена до логического завершения в CLU, а затем совершенно извращенным способом трансформировалась в шаблоны в С++.
Я не знаком с CLU и PL/I, и у меня возник вопрос: почему Вы считаете реализацию шаблонов в C++ извращенством? Вполне серьезная часть языка и не сложная для понимания. Все-таки шаблоны решают одну задачу ООП — дублирование кода. По сему считаю несправедливым бросать камни в сторону шаблоном.
Впрочем, если я заблуждаюсь, просьба «объяснить на пальцах» почему такое суждение неверно.
0
Претензии не к из существованию (наоборот, я их категорически приветствую), а к реализации. Для решения простых повседневных задач приходится решать головоломкм, а само написание шаблонов превращается в исскусство.
По сути шаблон это программа времени компиляции. И было бы значительно проще иметь синтаксис оперирующий информацией времени компиляции в этом месте. Что бы простые вещи типа проверки размера типа или выяснение самого типа параметров шаблона не превращались в набор трюков. Я очень уважаю Александреску за его труд, но я так же понимаю, что подвиг одних это, чаще всего, головотяпство других. Ситуация с шаблонами в плюсах как нельзя точнее описывается именно этим выражением.
+1
А не потому ли это, что шаблоны вроде как не метапрограммирование, а обобщенное программирование? Для метапрограммирования их можно применять, но раз оно изначально не для того предназначено — приходится удалять гланды через задницу.
+1
Вполне возможно.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.