Про ООП

Снова услышал такую точку зрения на объектно-ориентированное программирование (цитирую другое ее изложение):

С++ и обжектпаскаль — это приятный синтаксический сахар, что-то типа процедур. Что-то типа — в том смысле, что мы «инкапсулируем» некий функционал в более или менее закрытые кирпичики, у которых все потроха внутри и попортить их сложнее.

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

В общем, утверждается, что ООП — это некое расширение обычного процедурного программирования, делающее более удобным объединение структур данных и работающего с ними кода. Из этого очень часто делается вывод, что, допустим, C++ — это не более, чем ненужная надстройка над обычным C. Этому способствует, скажем, изучение библиотек WinAPI и MFC — так как вторая является «объектно-ориентированной оберткой» над первой, формируется представление, что ООП мало чем отличается от процедурного программирования.

Так ли это? Действительно ли повсеместное использование ООП — это дань моде? Хотелось бы думать, что нет. И сразу же обращу внимание на то, что библиотека WinAPI на самом деле спроектирована с использованием принципов объектно-ориентированного программирования — именно поэтому при сравнении WinAPI и MFC кажется, что «объекты» во второй дублируют «необъектные» понятия первой. ООП — это не замена записи вида f(h, a, b, c) на h.f(a, b, c), это совсем другое. Как определяет его Гради Буч (в книге «Объектно-ориентированный анализ и проектирование»),

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

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

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

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

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

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

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

PS На самом деле я это уже демонстрировал, правда, далеко не в «идеально чистом» виде.

Про ООП: 4 комментария

  1. >В общем, утверждается, что ООП – это некое расширение обычного процедурного программирования,

    А процедурное — это расширение структурного, а структурное — расширение программирования в кодах.
    И при каждом расширении, если ты не понял, добавляются новые принципиальные удобства.

    1. > добавляются новые принципиальные удобства

      С этим не спорю. На C++ удобнее писать в объектно-ориентированном стиле, чем на C.

      Дело не в удобствах, дело в том, что специальные «объектно-ориентированные» языки лучше поддерживают «объектно-ориентированную» методологию. У того же Страуструпа в «Языке программирования C++» приводятся примеры разных «парадигм программирования». Например, «процедурная» парадигма формулируется так:

      Реши, какие требуются процедуры; используй наилучшие доступные алгоритмы.

      «Модульное программирование»:

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

      «ООП» Страуструп формулирует так:

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

      Заметь, что модульное программирование решает чисто техническую проблему — скрытие данных, а ООП предполагает совершенно другой первый шаг — не от процессов (выражаемых процедурами), а от объектов (то есть классов).

  2. Связь ООП с Платоном — это ж готовый реферат для кандидатского минимума. Случаем не докторскую пишете?

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

    1. > Случаем не докторскую пишете?

      Не-е-ет, что вы :)

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

      Вот, и после этого ООП воспринимается, как «расширение» процедурного языка. Я вот тут в комментарии писал, что обучение «в историческом порядке» — оно не совсем правильное:

      http://nicka-startcev.livejournal.com/1131992.html?thread=3155160#t3155160

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *