Блог


Парадигмы ООП не существует или "Свободная касса!"

Эпотажный заголовок, не правда ли? Однако давайте разберемся.

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

Она существует только в нашем воображении. Так же как и парадигма ООП. 

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

К примеру Процедурная парадигма (её так принято называть по инерции, в PHP практически всегда используется её модификация - структурное программирование). Определение её недвусмысленно даже в банальной википедии:

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

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

Давайте представим себе ситуацию, что крутой ООПэшник устраивается на работу и проходит собеседование. А там такой зануда-очкарик в качестве интервьюера:

- Вы написали в резюме, что знаете ООП. Это верно?
- Да, разумеется.
- Расскажите, что такое ООП парадигма.
- Ну это парадигма программирования, основанная на классах и...
- Стоп. Вы хотите сказать, что в ООП обязательны классы? А как же JavaScript? Там нет классов, а ООП есть.
- Ммм, а, ну да. Не на классах, а на объектах и их взаимодействиях.
- Другими словами Вы утверждаете, что если программа содержит объекты, то это ООП?
- Нет, не просто содержит. А состоит только из одних объектов. Первый принцип концепции ООП, предложенный Аланом Кеем, которого считают его отцом-прородителем, гласит:
Всё является объектом.

- То есть Вы считаете, что кроме объектов в ООП ничего быть не может. Но как же тогда запустить программу? Создать экземпляр? Ведь оператор new, это процедурная директива.
- Ну... Да. 
- А другие опрераторы (instanceof к примеру), не являющиеся объектами, могут применяться в ООП?
- Могут, как же без них. 
- Но как же тогда постулат "всё является объектом"?
- Уточним:
Все должно является объектами, кроме нативных операторов и конструкций.


- А сам класс является объектом?
- Нет. Это абстрактный тип данных, на основе которого формируются объекты.
- Но он же может использоваться в парадигме?
- Да, разумеется. Как каркас для создания объектов.
- А статический класс PHP может использоваться в ООП?
- Нет. Ведь объект мы не создаем.
- А как же тогда паттерн Singleton? Или Registry?
- Действительно. Постойте, внутри языка все равно создается дефолтный объект, значит может использоваться.
- Но ведь ссылки на него нет и мы не можем работать с ним, как с полноценным объектом. Сериализовать, клонировать, передать аргументом и так далее. Значит это не совсем объект?
- Да, не совсем. Тогда нужно уточнить:
Всё должно являться объектами, кроме нативных операторов, конструкций и классов.

- Выходит программа, написанная на одних статических классах находится в рамках ООП парадигмы?
- Нет конечно. Это будет Класс-Ориентированное программирование :)
- Тогда как определить, что есть ООП программа? Если там 10 статических классов и один динамический объект, это ООП?
- Не думаю...
- А сколько? Каково процентное соотношение допустимо, чтобы считать программу Объектно-ориентированной?
- Не знаю. Это нигде не регламентировано.

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

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

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

- Что же изменилось?
- Почти ничего. Но постойте, дело скорее всего в состоянии. ООП предполагает некоторую многомерность вычислений на основе сохранения состояний объектов. 
- Вот. С этого места поподробнее.
- Дело в том, что объект может хранить свое состояние (значения свойств). И результат вычислений можно "замораживать", а так же изменять в ходе выполнения программы.
- Чем это отличается от обычных переменных в глобальной области видимости или от процедурной директивы static? 
- Тем, что это объекты.
- Но объекты можно использовать и в процедурной парадигме. Ведь они появились задолго до первой концепции ООП. Значит здесь тоже нужно конкретизировать и поставить обязательное условие:
ООП программа может использовать объекты, нативные операторы, конструкции и сатические классы. А так же может  использовать полиморфизм, наследование, инкапсуляцю и абстракции. Но обязательно должна сохранять состояние объектов на протяжении выполнения.

- Не получается... В ООП кроме понятия stateful есть еще и stateless. Модель stateful предполагает, что все методы объекта работают в контексте его состояния. В stateless общего контекста и состояния вовсе нет. Объекты похожи на библиотеки, сборники независимых функций.
- Но если сохранение состояния необязательно, а так же другим парадигмам "не запрещено" использовать объекты, то в чем соль? Давайте попробуем дополнить формулировку:
ООП программа может использовать объекты, нативные операторы, конструкции и сатические классы. Может  использовать полиморфизм, наследование, инкапсуляцю и абстракции. А так же может сохранять или не сохранять состояние объектов на протяжении выполнения.

- Это она может, но не обязательно. Похоже это на парадигму?
- Не особо.
- Так что же тогда еще есть?
- Остается только то, чего она не может. Или не имеет право.
- Что же именно?
- Можно я пойду... Всего доброго.

Вообще конечно же парадигма существует. Её разработал и анонсировал Алан Кей в лохматом 1972 году.  Но только она существует для чисто объектных языков. Таких как Smalltalk, для которого она и формулировалась. Звучит она так:

  1. Всё является объектом.
  2. Вычисления осуществляются путём взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие. Объекты взаимодействуют, посылая и получая сообщения. Сообщение — это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия.
  3. Каждый объект имеет независимую память, которая состоит из других объектов.
  4. Каждый объект является представителем класса, который выражает общие свойства объектов (таких, как целые числа или списки).
  5. В классе задаётся поведение (функциональность) объекта. Тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия.
  6. Классы организованы в единую древовидную структуру с общим корнем, называемую иерархией наследования. Память и поведение, связанное с экземплярами определённого класса, автоматически доступны любому классу, расположенному ниже в иерархическом дереве.


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

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

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

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

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

Причем одни из них отрицают колеса для машин, но не против дверей и окон для домов. Другие же наоборот.





И еще, работа в компании, которая строго придерживается методологии ООП, лично мне напоминает работу в McDonald's, а само ООП - фастфуд.

Точно так же нет общих прописанных концепций. И McDonald’s, и KFC, и даже банальный ларек с шавермой находятся в поле этой парадигмы. Нет никаких особых правил, однако объединяет их общий принцип. Быстро, по шаблону, с ограниченным ассортиментом. Ведь духовка дешевле, чем хороший повар. 

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

Очень легко рефакторится, достаточно добавить на булочку кунжут, и вот уже новое блюдо.

Легко тестируется, ведь не нужно дегустаторов, достаточно сравнить с эталонным чизбургером или бигмаком.

Тот же пиар, то же повcеместное распространение, та же популярность, тот же непретязательный уровень персонала.

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

И тот же "корпоративный дух". Не приведи Господи сказать работникам Макдональдса, что они травят население. Ты что! Они двигают прогресс, экономя время людей на еде. А кто не согласен - пусть идет жрать свою говно-яичницу с беконом и говно-борщ. А кому вообще неймется, пусть идет в ресторан и попробует разобраться в рецепте говно-супа Том Ям.

Так вот. Если вы считаете, что достигли вершин программирования, свято придерживаясь этих правил, оглянитесь и посмотрите вокуг внимательно. Весьма вероятно ваш удел всего навсего кричать "Свободная касса!" На просторах я нашел одно лаконичное определение назначению ООП (не знаю автора):

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


Скорее всего он перефразировал Пола Грэма:

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


Я вовсе не противник ООП методологии, как могло показаться. И тоже нет-нет, да и скушаю гамбургер с колой. Любая ложка хороша к своему обеду). Но загонять себя в искуственные рамки, которые при этом приходится самому для себя устанавливать - увольте. У современных языков программирования такие огромные возможности, что это было бы непростительным расточительством.

Такие авторитетные мэтры, как Пол Грэм, Ричард Габриел, Бьёрн Страуструп, Ричард Мэттью Столлман, наш соотечественник Александр Степанов и многие другие не стесняются признать себя адептами мультипарадигмы. Кто-нибудь посмеет назвать их говнокодерами? :)



В написани статьи использовались следующие материалы:

Objects Have Failed (Объекты провалились)
Why OO Sucks (не буду переводить :) )
OOP Is Much Better in Theory Than in Practice (ООП гораздо лучше в теории, чем на практике)
История объектно-ориентированного программирования
Языки программирования через сто лет
Я не знаю ООП

и многие другие, всего не упомнишь.


Ну и конечно же наш любимый форум.

Николай aka twin




Теги: PHP | Флейм

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


 
Наверх