Почти каждый день возникают дискуссии с критикой или восхвалением объектно-ориентированного программирования. «Java устарела!», «Java потрясающая!». В этой статье я проведу прагматичное исследование ООП на 2024 год.

Термин объектно-ориентированное программирование придумал Алан Кэй. Кэй был членом команды PARC, которая изобрела графический интерфейс пользователя, сделавший таким полезным современный Интернет, персональные компьютеры, планшеты и смартфоны. Ещё она изобрела некоторые из объектно-ориентированных языков, на которых мы сегодня реализуем эти GUI.

Если отсечь все эмоции, связанные с ООП, то что останется? По-прежнему ли ООП является эффективным инструментом разработки ПО, или оно превратилось в устаревшее увлечение? Профессионалам важно знать ответ на этот вопрос!

▍ Что Алан Кэй сказал про ООП


«Для меня ООП означает только обмен сообщениями, локальное удержание и защиту, сокрытие состояния и крайне позднее связывание».

Давайте разобьём это на составляющие:

  1. «Только обмен сообщениями» означает, что объекты общаются друг с другом при помощи сообщений. Сообщение объекту — это запрос на выполнение процедуры, то есть оно приведёт к изменению в состоянии одного или нескольких объектов или к возврату значения. Это подчёркивает, что объекты должны взаимодействовать через чётко определённые интерфейсы, используя сообщения для запросов действий.
  2. «Локальное удержание и защита, сокрытие состояния» означает инкапсуляцию и сокрытие информации. Инкапсуляция — это привязка данных к методам, работающим с этими данными, или ограничение прямого доступа к некоторым компонентам объекта. Сокрытие информации — это принцип сокрытия от пользователей подробностей реализации класса. Объект раскрывает только те операции, которые безопасны и релевантны для пользователя. Это защищает внутреннее состояние объекта и гарантирует, что объект можно будет использовать без необходимости понимания таящейся внутри него сложности.
  3. «Крайне позднее связывание» — под поздним связыванием подразумевается то, что конкретный вызываемый код определяется во время исполнения, а не во время сборки. Это позволяет обеспечивать более гибкое и динамическое поведение кода, при котором объекты различных типов можно использовать взаимозаменяемо при условии, если они предоставляют одинаковый внешний интерфейс, даже если внутри них действия реализуются по-разному. Позднее связывание описывает систему, максимизирующую эту гибкость, позволяя создавать очень динамическую и адаптивную модель компонентов.

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

▍ Чего он не сказал


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

  1. Производные классы (подклассы) сильно связаны со своими родительскими классами.
  2. Иерархии наследования могут усложнить понимание и трассировку кода.
  3. Изменения в базовом классе могут легко поломать его подклассы.
  4. Переопределение методов в подклассах может привести к непониманию того, какой экземпляр метода вызывается.
  5. Подклассы часто полагаются на знания о подробностях реализации родительских классов, что ломает инкапсуляцию.
  6. Изменение вышестоящего класса может потребовать обширных изменений во многих его подклассах.
  7. Подклассы добавляют дополнительные состояния и поведения, способные усложнить тестирование.

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

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

▍ Что же означает ООП для нас сегодня?


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

ПО само по себе сложно. Чем больше становится система, чем сильнее она меняется, тем сложнее обычно становится.

Рисунок 1: Зависимость сложности от количества компонентов. Сложность = n(n-1)/2

Как показано на Рисунке 1, сложность приложений существенно возрастает с увеличением количества составляющих приложение элементов и связей между ними.

Один из самых эффективных способов управления сложностью ПО — это применение моделей компонентов, которые:

  1. Упрощают понимание и изменение отдельных компонентов ПО.
  2. Изолируют компоненты ПО от изменений в других компонентах.
  3. Минимизируют потенциальные помехи командам, работающим над разными частями системы.
  4. Упрощают выпуск новых и обновлённых компонентов ПО.

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

▍ Почему мысли Кэя об ООП важны?


Фундаментальная проблема заключается в том, что разработка ПО — это сложный процесс.

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

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

Кроме того, экономически выгодно, чтобы готовые приложения можно было легко тестировать, непрерывно модифицировать и развёртывать. Ещё было бы неплохо, если бы приложения автоматически конфигурировались и самостоятельно выполняли мониторинг, были устойчивы к сбоям и горизонтально масштабировались, реагируя на нагрузки.

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

▍ «Только обмен сообщениями»


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

  1. Обмен сообщениями позволяет обеспечить слабое связывание между разными частями системы. Так как компоненты общаются посредством сообщений и не требуют знания внутреннего устройства друг друга, изменения в одном компоненте не влияют напрямую на другие. Это упрощает обновления и поддержку.
  2. Системы, спроектированные на принципе обмена сообщениями, проще масштабировать. Компоненты можно распределить по множеству серверов или процессов, а поскольку они общаются друг с другом через сообщения, система может справляться с повышенными нагрузками, добавляя больше ресурсов, без необходимости внесения существенных изменений в архитектуру.
  3. Обмен сообщениями сам по себе поддерживает конкурентность. Разные части системы могут обрабатывать сообщения одновременно, пользуясь преимуществами многоядерных процессоров и распределённых вычислительных ресурсов для повышения производительности.
  4. Так как компоненты общаются посредством чётко определённых сообщений, их можно реализовывать на разных языках программирования и с помощью разных технологий. Это позволяет разработчикам выбирать наиболее подходящие под требования каждого компонента инструменты.
  5. Системы обмена сообщениями можно спроектировать так, чтобы они были устойчивы к сбоям. В случае сбоя компонента сообщения можно попробовать отправить повторно или перенаправить другому экземпляру компонента, обеспечив доступность системы. Так как компоненты разделены, сбой в одной области с меньшей вероятностью приведёт к аварии всей системы.
  6. Обмен сообщениями упрощает интеграцию разделённых систем. Разные системы могут общаться при помощи обмена сообщениями, даже если они созданы на основе разных технологий и работают на разных платформах.
  7. Обмен сообщений естественным образом поддерживает и синхронные, и асинхронные операции: отправитель может передать сообщение и ждать ответа или же опубликовать событие и не ждать. Это может привести к более эффективному использованию ресурсов и повысить общую отзывчивость системы.
  8. В системе на основе обмена сообщений все данные в сообщениях передаются по значению, а не по ссылке, что гарантирует потокобезопасность и неизменяемость сообщений, а также невозможность создания ими побочных эффектов.
  9. В системе на основе обмена сообщениями перемещающиеся между компонентами сообщения можно логировать и отслеживать, обеспечивая наблюдаемость поведения и производительности системы. Это может быть очень ценно для отладки, настройки производительности и понимания взаимодействий в системе.
  10. Системы обмена сообщениями поддерживают транзакционный обмен сообщениями, что позволяет выполнять сложные операции с задействованием нескольких этапов, которые можно рассматривать как единую атомарную транзакцию. Это гарантирует согласованность и надёжность данных даже в случае частичных сбоев.
  11. Общающиеся через сообщения компоненты часто можно тестировать изолированно, симулируя входящие сообщения и наблюдая за ответами. Это упрощает создание интеграционных и юнит-тестов.

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

Рисунок 2: Стратегии обмена сообщениями

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

Рисунок 3: Оркестрация обмена сообщениями. Под процессом здесь подразумевается активный экземпляр виртуальной машины Java

В показанном выше примере сообщения M2-M4 исходят от Component 1 и доставляются целевым компонентам (2, 3 и 4). Карты адресов компонентов автоматически распространяются между оркестраторами.

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

Рисунок 4: Маршрутизация сообщений

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

▍ «Локальное удержание и защита, сокрытие состояния»


Эти принципы являются фундаментом для создания надёжного, удобного в поддержке и безопасного ПО. В разработке ПО эти принципы имеют следующие преимущества:

  1. Сокрытие внутреннего состояния объекта от внешнего мира, обеспечение доступа только через чётко определённый интерфейс. Это скрывает сложность управления состоянием и защищает целостность объекта, предотвращая перевод объекта в несогласованное состояние внешними сущностями.
  2. Локализация состояния и логики управления им внутри компонента, упрощение понимания и поддержки системы. Можно сделать так, чтобы изменения в управлении состоянием компонента минимально влияли на другие части системы.
  3. Повышает модульность благодаря тому, что позволяет разработчикам проектировать системы, в которых компоненты автономны и имеют чёткие интерфейсы для взаимодействия. Такая модульность помогает в многократном использовании компонентов в разных частях системы или в разных проектах.
  4. Защита состояния объектов от неавторизованного доступа — ключевой аспект целостности ПО. Скрывая состояние и раскрывая только управляемый интерфейс, система может обеспечить выполнение только авторизованных действий, снижая риск уязвимостей целостности.
  5. Инкапсуляция состояния и логики манипулирования им упрощает тестирование и отладку компонентов. Так как управление состоянием выполняется внутри компонента, разработчики могут сосредоточиться на тестировании поведения компонента в изоляции, прежде чем интегрировать его в систему.
  6. При управлении состоянием и поведением, а также при их инкапсуляции систему легче масштабировать или совершенствуя отдельные компоненты, или добавляя новые, соответствующие уже имеющимся интерфейсам. Такие локализация и управление состоянием обеспечивают возможность и вертикальной, и горизонтальной стратегий масштабирования.
  7. Защита внутреннего состояния компонентов и обеспечение управления всеми переходами между состояниями через чётко определённый интерфейс, благодаря чему система более устойчива к ошибкам и непреднамеренным побочным эффектам. Это повышает надёжность приложений.
  8. Обеспечение разбиения системы на отдельные фичи, функциональность которых пересекается минимально. Такое разбиение упрощает управление сложностью, так как разработчики могут единовременно заниматься только одним аспектом системы.

▍ «Крайне позднее связывание»


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

  1. Компонуемые компоненты, динамически загружаемые в среде исполнения для расширения функциональности приложения. Это вид компоновки, позволяющий приложениям иметь высокую степень расширяемости и настраиваемости.
  2. Языки, использующие JIT-компиляцию, например, Java и C#, компилируют код в среде исполнения, а языки наподобие TypeScript являются интерпретируемыми. Это позволяет создавать динамическую компоновку, при которой компилятор/интерпретатор и компоновщик могут оптимизировать исполняемый файл под конкретное оборудование, на котором он выполняется.
  3. При работе с микросервисами компоновка принимает новые формы. Сервисы общаются друг с другом по сети при помощи легковесных протоколов, по сути, компонуя распределённые компоненты во время исполнения.

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

У применения крайне позднего связывания в разработке ПО есть множество преимуществ:

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

▍ Подведём итог


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

Создание отзывчивого сетевого распределённого ПО, экономически выгодного в разработке и поддержке, работающего эффективно и надёжно, может быть сложной задачей. Алан Кэй многократно доказал, что использование ООП в том виде, каким оно задумывалось командой PARC, может помочь вам.

▍ Рекомендуемые материалы


  • Computer Software, Алан Кэй, Scientific American за сентябрь 1984 года
  • Component Software — Beyond Object-Oriented Software Клеменса Шиперски
  • В статье Composable Services рассказывается о том, что делает сервис компонуемым.
  • Designing with Composable Services — использование компонуемых сервисов для оптимизации компромиссов при проектировании приложений.
  • Building with Composable Services — более формальное и подробное описание паттерна проектирования компонуемых сервисов.
  • The Magic of Message Orchestration — знакомство со связями, объединяющими компонуемые компоненты.
  • Building Software Systems — о борьбе со сложностью разработки ПО.
  • Designing a REST API — о том, почему обмен сообщениями с использованием состояния лучше, чем удалённые вызовы процедур.

Telegram-канал со скидками, розыгрышами призов и новостями IT ?

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


  1. LabEG
    27.03.2024 13:27
    +74

    Лютая каша из отдельный фраз. И очередное неправомерное приписывание изобретения современного ООП Алану Кею.

    "Когда я говорил про ООП я имел ввиду совершенно не то что реализовано в С++" Алан Кей.

    То что имел ввиду Алан Кей это обычные словари на сигналах, единственный фреймворк кто ее придерживается это Qt, к тому ООП что мы используем не имеет никакого отношения. То ООП которое мы знаем было реализовано в С++ Страуструпом, далее распространилась по остальным языкам: Java, C# и т.п.. Соответственно вся статья больше похоже на бредогенерацию сгенерированную ИИ на общих фразах подчерпнутых из сети.


    1. DeepHill
      27.03.2024 13:27

      Комментарий похож на галюцинирование нейросети) Внешне выглядит правдоподобно но недостоверно и бессмысленно.


      1. Nurked
        27.03.2024 13:27
        +93

        Вот как раз его комментарий - связный и человекописный.

        А я за 25 лет программирования насмотрелся бесконечного количества статей о том, что та или иная технология ну вот вот ну вот щас уже умрёт, и вот ну вот вот щас вот уже скончается.

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

        Мне заливали, что PHP умер. Оказывается всё ещё живёт, и местами переплёвывает ноду.

        Я прочитал с пол-сотни статей, о том, что NPM - это жесть полная, и она вместе с нодой умрёт, потому что появился Бан, Дено или что-то там ещё. Ну да, так и есть, а в проде я всё так же вижу.

        Мне рассказывали о том, что NoSQL принесёт полную смерть и погибель SQL базам данных. Ага. Наверняка Стив Баллмер в то время, после прочтения этой статьи побежал закрывать отдел разработки MSSQL и оскользнулся, уплал и подвернул лодыжку. Только, очевидно, не добежал до закрытия.

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

        Даже Кобол называли мёртвым языком. Только вот его хотят учить щас.

        Ах, да, каждый день в интернетах выходит 2-3 статьи о новом убийце айфонов.

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

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

        Технологии не умирают под фанфары. Никто не делает публичных похорон. Никто не устраивает "Наконец-то мы победили!" Нет. Просто в один прекрасный день кто-то встрепенётся и скажет "Блин, мне надо обслужить паровой двигатель, пойду-ка я и найду специалистов", а поктом оказывается, что специалистов нет, ты уже никому не нужен, и все об этом давным-давно забыли. В такой момент можно написать статью-ретроспективу о том, что "в 1812-м году, когда Наполеон завоёвывал Россию, в мире существовали компьютеры на тренарной логике". А эти рассуждения по поводу того, что ООП нужен или не нужен - они абсолютно бесполезны.

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

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


        1. DeepHill
          27.03.2024 13:27
          +14

          Секта свидетелей «ооп это инкапсуляция, наследование и полиморфизм» очень агрессивна). То «ооп которое вы знаете» набор абстракции не имеющий прямой связи понятием ооп. Эти абстракции могут использоваться могут не использоваться в ооп подходе.


    1. sparhawk
      27.03.2024 13:27
      +17

      То ООП которое мы знаем

      Такое ощущение, что на просторах СНГ прижилось какое-то своё C++-ориентированное ООП, и на собеседованиях здесь на вопрос про основные принципы ООП ждут ответа абстракция-инкапсуляция-наследование-полиморфизм из Шилдта или Страуструпа. Языкам Python, JavaScript, TypeScript, Go отказано в праве называться тру-ООП

      В англоязычной статье на Википедии даже нет этой четверки принципов - там это всего лишь опциональные "фичи"


      1. SadOcean
        27.03.2024 13:27
        +5

        Я бы сказал что это основная проблема


      1. Spiritschaser
        27.03.2024 13:27
        +5

        на просторах СНГ прижилось какое-то своё

        Думаю, это всё наследие borland vcl :)


        1. geher
          27.03.2024 13:27
          +3

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

          А корни проблемы скорее в том, что "Страуструп - наше все". Именно он популяризовал наследование и виртуальные функции в качестве основы ООП.


        1. dmitryklerik
          27.03.2024 13:27
          +1

          Это наследие не очень хорошего обучения программированию в постсоветских вузах где теорию ООП объясняли не дольше одной пары в терминах инкапсуляции, полиморфизма, наследования а дальше сразу переходили к C++


      1. alguien
        27.03.2024 13:27

        Есть, они все упоминаются в разделе Features на англ. Wiki: Inheritance, Data abstraction and encapsulation, Polymorphism...


      1. sergey_prokofiev
        27.03.2024 13:27

        ООП в JS, который официально был разработан как функциональный язык программирования? Серьезно? В языке в котором десятилетия(!) функция-конструктор была основным способом создания "обьектов"? Сейчас конечно синтаксического сахара добавили, но с точки зрения ООП - это обнять и плакать. Вот в TS Хейлсберг нормально развернулся, и функциональщина, и ооп в лучшем виде и с опытом в десятилетия.


        1. unreal_undead2
          27.03.2024 13:27
          +1

          Прототипы - тоже вариант реализации ООП, ноги у Javascript растут из Self.


      1. gandjustas
        27.03.2024 13:27

        TS изначально, а JS примерно в 2017 получил классы и наследование, как в других C-подобных языках


    1. nin-jin
      27.03.2024 13:27

      В $mol используется ОРП, который является частным случаем того ООП, о котором говорил Алан - объекты, динамически провязываемые каналами, по которым бегут сообщения.


      1. ef_end_y
        27.03.2024 13:27
        +52

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


        1. nin-jin
          27.03.2024 13:27

          Работа у меня такая, хорошие вещи продвигать:

          А что вы хорошего делаете для индустрии своими едкими комментариями?


    1. arielf
      27.03.2024 13:27
      +30

      І тут у мене підгоріло!

      И очередное неправомерное приписывание изобретения современного ООП Алану Кею.

      Более чем правомерное. Именно Алан Кэй впервые сформулировал концепцию современного ООП и употребил это выражение.

      То ООП которое мы знаем было реализовано в С++ Страуструпом, далее распространилась по остальным языкам: Java, C# и т.п..

      Вот это вообще хтоническая чушь! Вы учили программирование на говнокурсах? То ООП, которое вы знаете -- это не ООП, а абстрактные типы данных. Многие их путают -- и это неправильно. ООП -- это объекты и обмен сообщениями.

      Впервые же объектные принципы (объекты, классы, наследование и иные вещи) были реализованы в 1961 - 1967 в языке Simula. Это самая ранняя реализация некоторых концепций ООП.

      Страуструп не изобрел ООП, он взял его из Simula. И ООП в C++ является набором костылей, прикрученных поверх C, и нужных, чтобы улучшить скорость выполнения. Нормальная реализация ООП поверх C есть в Objective-C.

      Но вернёмся к истинному ООП. Гений Алан Кэй, посмотрев на Simula, понял, что можно сделать ещё лучше. И в 1967 впервые сформулировал концепцию современного ООП и, что принципиально, употребил это выражение в разговоре. Так что именно он является отцом современного ООП.

      Первый язык, реализующий современное ООП вышел в 1972, и это был Smalltalk. Он вполне жив и применяется в промышленном программировании.


      1. werevolff
        27.03.2024 13:27
        +14

        Холивар-то какой.

        По другим источникам, изобретение Объектно-ориентированного подхода приписывается Оле-Йохану Далю и Кристену Нюгору, которые в 1966 году нашли возможность перенести кадр стека вызова функции - в динамическую память (на языке ALGOL). Что открыло возможность инкапсуляции, а затем - полиморфизма - через строгое использование указателей на функции.

        Отсюда следует, что, во-первых, изобретение ООП не стоит приписывать отдельным людям. Это как радио Попова. Разные разработчики шли к этому открытию разными путями. Во-вторых, делать из ООП какую-то священную доктрину - это детский сад. У нас есть три основные парадигмы программирования: структурное, ООП, функциональное. И есть некоторое подмножество таких парадигм, как императивное, процедурное, параллельное. Часть из них можно связать с базовыми тремя. Часть больше похожи на стили, поскольку предлагают лишь философию, а не конкретику на уровне управления памятью и процессом. Часть - устарела. Поэтому, можно сказать, что кроме три базовых парадигм, других нет и не будет. По крайней мере, на современных нам вычислительных системах. Все они используются в той или иной мере каждый день. Структурное программирование предлагает нам использование циклов и условных операторов вместо прямого вызова строк кода (прямой передачи управления). Здесь можно сказать, что структурное программирование заменило императивное, доказав вред прямой передачи управления. Поэтому,то же самое процедурное программирование можно условно отнести к подмножества структурного из-за необходимости избавляться от прямых переходов. ООП определяет программные сущности, как изолированные (в том числе, физически - в памяти) объекты и определяет правила работы с ними. Функциональное программирование расширяет наш кругозор лямбда-исчислением, предлагая отказываться от изменения переменных и хранения состояния программы.

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

        Поэтому, вся статья напоминает рассуждения в стиле "нужен ли ЦП современному компьютеру, или можно впихнуть в материнку картофелину"? Комментарии - вообще дичь. Парадигмы программирования связаны непосредственно с тем, как работают современные вычислительные системы, обрабатывающие биты. Это не концепции, это не философия. Это доказанные рабочие процессы. Поэтому, не так важно кто сформулировал те или иные принципы. Эти принципы - как законы природы. Если бы не было возможности разместить кадр стека вызова функции в динамическую память, не было бы ООП. Если бы не работала теорема Бëма-Якопини, не было бы структурного программирования. Если бы лямбда-исчисления были невозможны, не было бы и функционального подхода.

        Всë обсуждение этой темы, почему-то, сводится к тому, что без Ньютона не было бы силы притяжения Земли. Так можно и до теории плоской Земли дойти, если начать спорить с концепциями Галилея и Коперника.


        1. nin-jin
          27.03.2024 13:27
          +3

          Декларативная и логическая парадигмы тихо плачут в сторонке из-за того, что вы их отменили.


          1. werevolff
            27.03.2024 13:27
            +3

            Ну, начнëм с того, что на существовании 3 основных парадигм настаивает Роберт Мартин. А закончим тем, что HTML и SQL - не совсем языки программирования (декларативные языки не являются Тьюринг-полными), ну а логическое программироаание является вариацией программирования с использованием лямбда-исчисления, то есть, вариацией функционального программирования. О чëм, собственно, и говорит отнесение современных логических языков к функционально-логическим.


            1. nin-jin
              27.03.2024 13:27

              И кто такой этот ваш Роберт Мартин?

              От отсутствия тьюринг-полноты язык не перестаёт быть языком программирования. К тому же есть и тюринг-полные декларативные языки.

              И где вы тут нашли лямбда-исчисление? https://ru.m.wikipedia.org/wiki/Пролог_(язык_программирования)


              1. werevolff
                27.03.2024 13:27

                И кто такой этот ваш Роберт Мартин?

                И где вы тут нашли лямбда-исчисление? https://ru.m.wikipedia.org/wiki/Пролог_(язык_программирования)

                Всё понятно. Удачи на курсах.


                1. nin-jin
                  27.03.2024 13:27

                  Спасибо. Кстати, записывайтесь, они того стоят: https://page.hyoo.ru/#!=wna7bl_3y0m1s


                  1. werevolff
                    27.03.2024 13:27
                    +1

                    OMG!

                    Tommy.jpeg


            1. igormu
              27.03.2024 13:27

              Рекурсивный SQL является Тьюринг-полным.


              1. werevolff
                27.03.2024 13:27

                С ограничениями.


                1. igormu
                  27.03.2024 13:27

                  Какими ограничениями? Технические ограничения есть абсолютно в любом языке - память не бесконечна.

                  Вот, например, интерпретатор Brainf__k в SQL-запросе.


                  1. werevolff
                    27.03.2024 13:27
                    +1

                    Ну, с определëнными допущениями, условиями и расширениями, тьюринг-машину можно собрать теоретически на чëм угодно. Это как Doom, который можно запустить хоть на хвосте собаки.

                    И всë-таки, я бы поставил под сомнение декларативность некоторых операций, которые делают такие языки, как SQL, тьюринг-полными. Например, операцию with. Он не описывает спецификацию ожидаемого результата, а, по сути, создаëт цикл.

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


                    1. arielf
                      27.03.2024 13:27
                      +1

                      Ну, с определëнными допущениями, условиями и расширениями, тьюринг-машину можно собрать теоретически на чëм угодно.

                      Щито? Это математика, в ней теорема или верна, или не верна. Она не может быть верна наполовину. Язык или тьюринг-полный, или не трьюринг-полный. Если его семантика эквивалентна машине Тьюрига, он тьюринг-полный.


                      1. werevolff
                        27.03.2024 13:27

                        Хм. Думаю, вы путаете математическое и чëрно-белое мышление. Язык SQL с расширениями перестаëт быть декларативным, приобретая черты императивного и функционального. Поэтому, со своими расширениями он и определяется в различных источниках, как мультипарадигменный.


                      1. arielf
                        27.03.2024 13:27

                        Речь про конкретную цитату. Вот про эту:

                        Ну, с определëнными допущениями, условиями и расширениями, тьюринг-машину можно собрать теоретически на чëм угодно.

                        Причём вообще SQL или иной язык?


            1. piton_nsk
              27.03.2024 13:27
              +1

              Ну, начнëм с того, что на существовании 3 основных парадигм настаивает Роберт Мартин

              Мартин это истина в последней инстанции?


              1. werevolff
                27.03.2024 13:27
                +1

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


                1. piton_nsk
                  27.03.2024 13:27
                  +1

                  Ну это же классическая отсылка к авторитету.


                  1. werevolff
                    27.03.2024 13:27

                    То есть, вы считаете, что приводить мнение технических авторов нельзя только потому, что это апелляция к авторитету?


                    1. piton_nsk
                      27.03.2024 13:27
                      +1

                      Почему же, можно. Но насколько это будет убедительно? Мартин и откровенную ерунду писал.


                      1. werevolff
                        27.03.2024 13:27

                        Уверен, что вы - тоже.


                      1. piton_nsk
                        27.03.2024 13:27

                        И на солнце бывают пятна)


                      1. Foxfail
                        27.03.2024 13:27

                        А у Вас как раз классический аргумент к личности. Возможно у Вас есть доводы которые противоречат утверждению Мартина, помимо того что он писал ерунду?


                      1. piton_nsk
                        27.03.2024 13:27

                        А у Вас как раз классический аргумент к личности.

                        Возможно я неудачно выразился. Само по себе использование мнения Мартина как аргумент идея сомнительная.

                        Возможно у Вас есть доводы которые противоречат утверждению Мартина, помимо того что он писал ерунду?

                        Чтобы сказать точно, надо бы посмотреть где, когда и что именно писал/говорил Мартин. В изначальном сообщении никакой ссылки нет. Поэтому все зависит от контекста. Нет четкого определения, есть разные мнения какие парадигмы основные, какие побочные. Опять же в современном прикладном ПО нет четкого разделения, код часто бывает в смешанном стиле написан. Короче говоря для таких утверждений нужна развернутая аргументация. А тут вместо аргументации чисто мнение Мартина, причем без ссылки, чтобы можно было понять контекст.

                        Теперь по существу вопроса.

                        Вот, к примеру, цитата из статьи Флойда (автор самого термина) 1978 года "Парадигмы программирования"

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

                        Как вам парадигма "разделяй и властвуй"? Там же упоминается парадигма динамического программирования. Или "для этого я создал парадигму нахождения иерархической организации процессоров". Очевидно, что под парадигмой программирования имеется в виду более узкие вещи чем ОО или структурное программирование.

                        А вот статья которая так и называется "Overview of the four main programming paradigms". Тут четыре основных парадигмы - императивная, функциональная, объектно-ориентированная и логическая.

                        Вот статья "Programming Paradigms for Dummies: What Every Programmer Should Know", там на " Figure 2. Taxonomy of programming paradigms " вообще "There are 27 boxes, each representing a paradigm as a set of programming concepts.". 27 парадигм, да еще целая таксономия со связами и прочим.

                        Есть разделение на императивную и декларативную, со своими более специализированными парадигмами.

                        Что в итоге? Понятие не очень четко сформулированное, есть самые разные взгляды на то сколько парадигм вообще, какие основные, какие специализированные. Поэтому утверждение "есть три основные парадигмы" и аргументация - так говорил Заратустра Мартин, мне представляется крайне упрощенным и как минимум спорным.

                        by the way, читали ли книгу Мартина "Agile Principles, Patterns, and Practices in C#" ?


                      1. werevolff
                        27.03.2024 13:27

                        Возможно я неудачно выразился.

                        Возможно (скорее, точно), вы не только неудачно выразились, но и проигнорировали ту часть моих комментариев, в которых приводились доводы того, что можно выделить три основных парадигмы, а прочие являются или устаревшими, или производными от них.

                        Что в итоге? Понятие не очень четко сформулированное, есть самые разные взгляды на то сколько парадигм вообще, какие основные, какие специализированные.

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

                        Структурное программирование - это имплементация теоремы Бёма-Якопини, которая ограничивает использование других способов передачи управления (например, оператора GOTO, по которому проехался в 1968 году Эдсгер Дейкстра).

                        Так а что же делать с императивным стилем? Я лично не считаю императивное программирование парадигмой. Это как называть Vanila JS фреймворком. Написание последовательных инструкций - это вообще не стиль. Это примитив разработки. Отсутствие структурирования. Когда мы ограничиваем методы передачи управления между отдельными строками кода ветвлениями и циклами, мы автоматически выходим на структурное программирование.

                        Как вам парадигма "разделяй и властвуй"?

                        Никак. Это логический паттерн, а не парадигма. Парадигма подразумевает набор правил написания кода, структурирования и оформления, потенциально независимо от языка программирования. То есть, мы можем применить одну из парадигм потенциально в любом языке. Хотите применить ООП в SQL? Пожалуйста! Помимо того, что существует Object-Pl/SQL, некоторые СУБД являются объектно-реляционными и позволяют, например, наследовать таблицы (https://www.cybertec-postgresql.com/en/conditional-foreign-keys-polymorphism-in-sql/). Скажу больше: оператор With в SQL наравне с применением оконных функций и Match/Case, по сути, позволяет применять структурный подход, расширяя декларативно-императивные инструкции языка циклами и ветвлениями. Кроме того, в многие СУБД позволяют писать свои функции, не сохраняющие состояние в процессе выполнения, применять цепочки вызовов функций, что делает SQL с расширениями, в том числе, функциональным языком.

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

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

                        Теорема Бёма-Якопини говорит о том, что любой алгоритм может быть оптимизирован до использования основных структур: последовательность, ветвление, цикл. Если некий язык не поддерживает одну из перечисленных структур, то он не полноценен, поскольку на нём не получится выполнить любую задачу.

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

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


                      1. arielf
                        27.03.2024 13:27

                        Когда мы говорим о парадигме ООП, то мы имеем ввиду вполне конкретные вещи.

                        Именно. И эти вещи: (1) всё есть объект и (2) объекты взаимодействуют путем посылки сообщений. Вот и все принципы. Всё прочее -- это частности реализации.

                        А именно, возможность инкапсуляции методов и свойств в классы с применением наследования и полиморфизма.

                        Классы и наследование -- это частный случай реализации. Есть языки, в которых вместо них используются прототипы и композиция. Слово "полиморфизм" вообще не люблю. Что оно значит вне конкретных языков? В терминологии C++ полиморфная функция может принимать аргументы разных типов. Причём тут ООП? Это ближе к метапрограммированию. То, что разные объекты по разному отвечают на одни и те же сообщения -- является их базовым свойством.

                        Ещё у вас противоречащие пункты. Вот вы пишите, что:

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

                        Угу, то есть частности низкоуровневой реализации сделали возможным ООП. Ну, хорошо. Но ниже, вы уже ставите телегу впереди лошади:

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

                        То есть ООП нужно, чтобы сохранить состояние вызова функции? Причём тут вообще вызовы и состояния функций? Почему вы их пихаете во все комменты?

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


        1. yulObraz
          27.03.2024 13:27
          +1

          Не совсем согласна что:

          Парадигмы программирования связаны непосредственно с тем, как работают современные вычислительные системы, обрабатывающие биты. Это не концепции, это не философия.

          Человек знакомый с данными "концепциями и философиями" пишет по другому на языках, не имеющих данных концепций в архитектуре (том же ассемблере).

          Да, есть противоречия в рассуждениях об устаревании концепции, когда она влилась в архитектуру.


          1. werevolff
            27.03.2024 13:27

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


            1. vanxant
              27.03.2024 13:27

              падажжите, а как декларативность противоречит ООП?


              1. werevolff
                27.03.2024 13:27

                Никак.


        1. Amega
          27.03.2024 13:27
          +1

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


        1. sved
          27.03.2024 13:27

          ООП явно не тянет на отдельную парадигму, это всего лишь, скажем так, частный случай Dinamic Dispatch, причём самый простой вариант - single dispatch.

          ООП появилось во времена графических интерфейсов и хорошо подходит именно как API для общения с операционной системой.

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

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

          А вот "pattern matching" и логическое программирование - действительно отдельные парадигмы, для них и матмодели имеются, так что утверждение, что других парадигм "нет и не будет" очевидно абсурдно


          1. vanxant
            27.03.2024 13:27

            ООП явно не тянет на отдельную парадигму

            ООП появилось во времена графических интерфейсов

            Нет конечно. ООП родилось в эпоху тотального доминирования процедурного программирования, и я не про SmallTalk, который по практичности и распространённости уступал языку Лого. И пыталось лечить проблемы процедурщины, когда все кишки наружу (привет DTO), и добавление одного подвида чего-то-там приводило к необходимости перелопатить все switch в программе.


    1. SergejSh
      27.03.2024 13:27
      +3

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


      1. saboteur_kiev
        27.03.2024 13:27
        +1

        Сделать программу проще - это не ооп, ооп это сделать разработку проще =)


        1. SergejSh
          27.03.2024 13:27

          Программу тоже. У меня на текущем месте работы нет ООП. В результате логика повторяется во многих местах, куча ветвлений и т. п.


    1. gandjustas
      27.03.2024 13:27
      +1

      Алан Кей придумал не само ООП, он ввел термин ООП для парадигмы Smalltalk (наиболее похожий представитель из сегодняшних мейнтрим языков - Python) уже после появления соответствующих концепций в других языках.

      Само ООП как мы его видим в большинстве статически типизированных языков придумали в Simula, а основным популяризатором стал Страустрп, который написал свой дисер на Simula и перенес его концепции на C, создав C++.


    1. chaetal
      27.03.2024 13:27

      Значит, то ООП, которое вы знаете — не ООП.


  1. SUNsung
    27.03.2024 13:27
    +5

    И все как всегда.

    Актуально ли ООП? Да

    Умеют ли програмисты с ним работать? Зачастую нет

    .

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

    .

    Самое печальное в этом всем, что неумение в ООП не означает умение в функциональное програмирование( Сейчас большая часть продуктов адская вермишель легаси, которую спасает только тотальное покрытие тестами


    1. markmariner
      27.03.2024 13:27
      +11

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

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

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


      1. SUNsung
        27.03.2024 13:27
        +4

        Задача програмистов решать задачу.

        Задача хороших програмистов решать задачу так, что бы решение не порождало собой новые проблемы

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

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

        .

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

        С таким отношением я не спорю что "большинство" совершенно не понимает базовые вещи, считая их "сложными".

        Единсвенное что спасает и ужасает - chatGPT позволил таким "погромистам" еще лучше мимикрировать.

        А потом охреневаешь от "решения задачи" которая выжирает в 20 раз больше оперативной памяти чем должно, потому что програмист вообще не понимает разницы между передачей среза и ссылки на срез, а тот метод что ему написал chatGPT не работает с ссылкой правильно.


        1. markmariner
          27.03.2024 13:27
          +7

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

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

          Говнокодинг, к примеру, тоже не страшен, потому, что проект сдохнет через 3 года сам из-за переориентации бизнеса.

          На деле, предположу, что там, где оперативная память важна (программирование игр), и где важна поддержка кода (программа будет выполняться годами на МКС) с этими требованиями всё хорошо.

          Поймите, отсутствие соответствия кода принципам ООП или функционального программирования = говнокодинг -- это ваше субъективное суждение.


          1. SUNsung
            27.03.2024 13:27
            +4

            Воистину в царстве горбатых прямая спина будет считатся уродством.

            И вы опять вцепились в принципы програмирования, когда я с самого начала говорю о том что важно не средство или принцип, а умение и понимание.


            1. markmariner
              27.03.2024 13:27
              +3

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

              на самом деле это потому, что никаких доказательств того, что ООП хорош у вас и нет


              1. SUNsung
                27.03.2024 13:27

                Ну приведи же цитату из моих коментариев (можно даже не только из первого) где я такое говорю.

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

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


                1. markmariner
                  27.03.2024 13:27

                  решил заменить свой комментарий на этот, чтобы не плодить ненависть

                  Оки


          1. opusmode
            27.03.2024 13:27
            +4

            Смотрите, я вот это слушаю уже много лет. Одну и туже сказку. По факту у вас ошибка выжившего. Ну, в реальности оно вон как бывает:

            1. Бизнес, которому надо "сейчас-сейчас-сейчас" платит много денег непонятно кому, кто говнокодит.

            2. Оно как-то выкатывается, запускается и работает.

            3. Оно требует заваливать это ресурсами, которые ну как бы типа дешевле.

            4. Бизнес рад, ведь запустилось.

            5. Через 2-4 года действительно всё умирает из-за переориентации бизнеса.

            Где же тут проблемы?

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

            Следовательно когда вы сравниваете память с часом работы программиста, вы делаете вид, что это равные величины, а это тёплое с мягким и при рассчёте на жизненный цикл выясняется, что заплатить разрабу за нормальную работу было выгонее .

            Проблема вторая - всегда говорю, что "работает" это самая нижняя планка оценки, ниже которой с исполнителем говорить просто больше не о чем.

            Хорошая оценка это "работает и соответствует вот таким критериям".

            Ну, это знаете, есть копейка, а есть порш. И там и там руль, 4 колеса и они могут ездить, но есть пара нюансовю

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

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

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


            1. markmariner
              27.03.2024 13:27

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


              1. opusmode
                27.03.2024 13:27

                Подождите, но этого никто и не утверждал. Конечно не для всех. Только вы в своём комментарии не говорите об этом. Фактически вы говорите "если тебе е хватает уровня и ты не освоил какую-то концепцию - игнорируй и делай как умеешь. Главное делать". Я, да и не только я, противопоставляем вам - простите, но это путь вникуда.

                И никто не говорил, что функциональная разработка, допустим, это говнокод. Если вы сделали такое предположение, то вы ошиблись. Вам говорят, что именно "пишется как пишется" это плохо. И это плохо в целом как тенденция, потому с этим необходимо бороться, ведь это намеренное понижение уровня. Так мы дальше скажем что-то типа "зачем все эти алгоритмы, мапинги, коллекции, декораторы, переменные и прочие странные слова? Не надо осваивать, пиши как умеешь".

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

                Более того, фактически такой подход показал себя очень хорошо и в других сферах. Фактически мы перешли от микроуровня к макроуровню с теми же идеями. Есть микросервисы, это развитие идеи. Есть подходы в инфраструктуре, где "один контейнер - один процесс". Т.е. мы изолируем сущности - одни хранят, другие обрабатывают. И взаимодействуют они друг с другом простыми операциями, а не мы лепим комбаин, который делает всё и сразу внутри себя.


      1. SadOcean
        27.03.2024 13:27
        +1

        Вопрос еще в том, а что является альтернативой?
        Структурное и функциональное программирование?


        1. markmariner
          27.03.2024 13:27
          +1

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


          1. SadOcean
            27.03.2024 13:27

            Ну если нет альтернативы, то даже самый неэффективный инструмент - лучший.


            1. opusmode
              27.03.2024 13:27

              Увы, но нет.

              Лучший это прилагательное, которое используется при сравнении. Т.е. мы могли бы разложить "лучший на" "инструмент А более эффективный, чем инструмент Б" и подобные состовляющие. Но если есть только инструмент А, он не может быть сравнен с чем-то. Потому если нет альтернативы, то инструмент безальтернативный, а не лучший.

              При этом, если он неэффективный или серьёзно проваливающийся по каким-то параметрам и это очевидно (не всегда можно в моменте узнать, что инструмент неэффективный. Например несколько сотен лет примерно никто не знал, что есть такая вещь, как электричество, а следовательно никто не знал, что свечи неэффективны, как и керосиновые лампы), стоит заняться поиском альтернативы.


        1. SergejSh
          27.03.2024 13:27
          +1

          Ответ на этот вопрос я ожидал прочесть в статье.


      1. SquareRootOfZero
        27.03.2024 13:27
        +2

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

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


        1. markmariner
          27.03.2024 13:27

          Нет, конечно, вы выворачиваете наизнанку все.

          если каждому хирургу рассказывают в вузе (как это происходит с ооп), что вот есть прекрасный скальпель (из вашего примера), и что это стандарт скальпелей и нужен каждому, а потом его использует на практике 1 из 100 хирургов, и никто не уволен, и люди не жалуются, то конечно плох скальпель или, как минимум, он нужен не всем.

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

          но я уверен, что вы это знаете и передергиваете специально, авось кто из аудитории не поймет разницы


          1. SquareRootOfZero
            27.03.2024 13:27

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


            1. markmariner
              27.03.2024 13:27

              Так топикстартер говорит, что надо, именно поэтому, мол, он и не решает задач потому, что программисты никак не могут научиться его использовать.

              вы вообще в курсе о чем я спорю?


              1. SquareRootOfZero
                27.03.2024 13:27

                Вы там написываете, что ООП плохо "для большинства задач программирования", то ли само по себе, то ли потому, что никто не умеет пользоваться, то ли никто не умеет пользоваться, потому что оно плохо само по себе - в любом случае плохо. Обычно про это любят писать упоротые адепты ФП, только вот их хаскели что-то никак не взлетают - лично мне, кстати, жаль, что не взлетают, потому что ФП тоже нормальный и рабочий инструмент для организации кода, не лучше ООП, просто другой, и ни то, ни другое не является "серебряной пулей". Чем я должен "подкрепить" своё мнение, я не представляю. Да и вы своё, что ООП плохо, не вижу, чтобы чем-то подкрепляли.


                1. markmariner
                  27.03.2024 13:27

                  Ну если у вас с пониманием текста проблемы, но я тут не помогу


            1. markmariner
              27.03.2024 13:27

              Ну и нет разницы — это вы просто выразили свое мнение, никак его не подкрепив. Второе предложение вообще о другом


      1. Yuriy_75
        27.03.2024 13:27
        +4

        Слышал о случаях, когда в конторе при использовании того же С++, просто на уровне стандарта разработки принималось "никакого наследования". Типа, возможность есть, но сами себе ее запретили, чтобы потом не разбираться с последствиями.


        1. CrashLogger
          27.03.2024 13:27

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


          1. markmariner
            27.03.2024 13:27
            +1

            Так нет, потому, что наличие наследования хорошо и обязательно для поддерживаемого кода — это не факт, а мнение

            А вам представляется, что это как земля крутится вокруг солнца, непреложный факт, многократно подтвержденный


            1. CorwinH
              27.03.2024 13:27
              +3

              Так нет, потому, что наличие наследования хорошо и обязательно для поддерживаемого кода — это не факт, а мнение

              Я бы добавил, что данное мнение уже не очень популярно в современном программировании. Множественное наследование редко встретишь в современных ЯП. Наследование от интерфейса заменяется (тенденция) на типажи (traits). Всё больше классов в типичном C# проекте не имеют базового (класс object не считаем). Всё шире используются статические классы и лямбда функции.


              1. funca
                27.03.2024 13:27
                +1

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


          1. Yuriy_75
            27.03.2024 13:27
            +2

            Аналогия всего лишь аналогия.

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


        1. ZirakZigil
          27.03.2024 13:27

          Прямо таки просто наследования? Не "никакого множественного", не "никаких виртуальных функций", а именно "никакого наследования вообще"?


          1. Yuriy_75
            27.03.2024 13:27

            Да, никакого.


        1. SquareRootOfZero
          27.03.2024 13:27
          +1

          Мне часто говорят, что студентам не разрешается использовать некоторые части Си или Си++ (обычно это указатели), потому что они "нечитаемы". Обычно это правило навязывается руководителями, знающими ФОРТРАН, БЕЙСИК или какой-то другой язык, не поддерживающий указатели, ибо их не очень-то заставишь изучать Си. Вместо того, чтобы допустить, что их знания недостаточны, такие руководители будут лучше калечить своих программистов. Указатели отлично читаемы для программистов на Си.

          Ален И. Голуб, "Веревка достаточной длины, чтобы… выстрелить себе в ногу", 1995 год.


  1. foxnorth228
    27.03.2024 13:27
    +1

    Подклассы сильно связаны с родительскими? Так, может, в этом и смысл подклассов?


    1. SadOcean
      27.03.2024 13:27
      +2

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

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

      Но мы зачастую имеем противоположное.
      Чтобы понять класс B во всех нюансах, нужно не только прочитать его базовый класс, но и ознакомиться со всеми прочими наследниками.


    1. kekoz
      27.03.2024 13:27

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


      1. lorc
        27.03.2024 13:27
        +5

        Ну то что в C++ нет отдельного понятия "интерфейс" - это проблема C++, а не ООП.


        1. kekoz
          27.03.2024 13:27

          Так и я предъявляю претензии не ООП, а именно C++. Ироническое Кэевское отношение к C++ совершенно понятно любому, кто пришёл в ООП ещё до появления C++.


        1. tonx92
          27.03.2024 13:27
          +1

          В go например реализация интерфейса каким либо классом не требует никакого наследования или даже ссылки на класс. Просто свойства и функции должны биться с интерфейсом.


          1. funca
            27.03.2024 13:27

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


        1. mrcashe
          27.03.2024 13:27

          Ну, польза от интерфейса в плюсах - сомнительна. По сути, породит дополнительный вид наследования вместо сегодняшней совершенно ортогональной системы наследования.
          Зачем интерфейсы в PHP? Потому что нет множественного наследования.


      1. ZirakZigil
        27.03.2024 13:27
        +2

        не может быть речи о полиморфизме

        Полиморфизмы разные бывают.

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

        Конечно же можете.


        1. kekoz
          27.03.2024 13:27
          +1

          Да-да, ООПы тоже разные бывают. И по поводу С++ООП Кэй выразился достаточно ясно :)


          1. ZirakZigil
            27.03.2024 13:27

            Да ради бога, пусть выражаются на здоровье. Благо, плюсы не обязывают использовать ооп ну вообще никак. И полиморфизмы от отказа от ооп тоже никуда не деваются.


  1. vvbob
    27.03.2024 13:27
    +11

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


    1. iRusher
      27.03.2024 13:27

      Я вообще не программист, немного изучал Python, сейчас пробую себя в инди разработке на движке Godot, там как раз писали про схожесть с питоном и ООП направленность движка. Я сначала пробовал создавать не очень трудные классы, чтобы например инициализировать повторяющиеся вещи типо: базовый урон скила, название, тип урона, максимальный лвл и тд. А остальное дописывал в коде каждого скила, но позже начал видеть многие закономерности и уже переносил в базовый класс больше и больше, в целом это прикольно, и где то мне очень помогло выгрузить из головы лишнего, упростить создание нового и сэкономить время, была необходимость пару раз, когда базовый класс не подходил под сценарии и механики нового скила или кнопки, ну написал "в ручную". Все же считаю пользы от этого больше.


  1. randomsimplenumber
    27.03.2024 13:27

    Витриной ООП, кмк, было старинное Delphi с его иерархией классов.


    1. alan008
      27.03.2024 13:27
      +1

      Не трогать Delphi, он живёт и здравствует и на нем пишут крупные проекты до сих пор. Новая версия в апреле вот выйдет


    1. checkpoint
      27.03.2024 13:27
      +4

      Оконный GUI, пожалуй, единственная сложная сущность которая хорошо ложиться на концепцию ООП. Не без изьяна разумеется. Первый ООП язык Smalltalk был придуман для реализации оконного интерфейса на Xerox Alto.


    1. HemulGM
      27.03.2024 13:27

      Старинное Delphi выпустила 12ую версию среды и компилятора в этом году


      1. Vitimbo
        27.03.2024 13:27

        Но зачем


        1. HemulGM
          27.03.2024 13:27
          +2

          Потому что есть спрос. Потому что удовлетворяет потребностям. Проблем у языка и инструмента с решением современных задач - нет.


  1. gochaorg
    27.03.2024 13:27
    +1

    Сомнительная статья

    Системы обмена сообщениями  поддерживают транзакционный обмен сообщениями

    Ну вот как бы не следует что наличие сообщений обязательно приводит к поддержке транзакций

    через обмен сообщениями, существенно повышается модульность, надёжность и масштабируемость.

    надежность понятие по ширше чем  устойчивы к сбоям

    например доступность - сегодня одно rest api, а завтра другое и как бы все ломается


  1. arielf
    27.03.2024 13:27
    +4

    Почему не упомянуты прототипные языки Self и JavaScript, в которых нет классов? И вообще, классы не являются непременным атрибутом ООП.


    1. TAZAQ
      27.03.2024 13:27

      Классы в жсе уже учатся в четвёртом классе


      1. arielf
        27.03.2024 13:27
        +1

        Ну это же синтаксический сахар. Они реализованы поверх прототипов.


        1. vanxant
          27.03.2024 13:27

          Если вы заглядывали внутрь js-движков, то чаще скорее наоборот - прототипы компилятся в классы.


  1. 0x131315
    27.03.2024 13:27

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

    Для себя в целом пришел примерно к тем же принципам, исходя из опыта и прошлых ошибок:

    • максимально строгий и простой публичный интерфейс, скорее даже контракт, он упрощает понимание и сокращает количество ошибок, делает взаимодействие частей системы прозрачным, повышает надежность и стабильность всей системы

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

    • принцип позднего связывания, на мой взгляд, автоматически вытекает из использования публичных интерфейсов: когда все взаимодействие частей системы строго расписано, уже не особо важно как и из чего сделана каждая отдельная часть, главное чтобы они придерживались публичного интерфейса. Их можно прозрачно менять, прямо во время работы системы, комбинировать, маршрутизировать каналы сообщений, архитектура такой системы очень гибкая

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


  1. snuk182
    27.03.2024 13:27
    +4

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


    1. SquareRootOfZero
      27.03.2024 13:27

      Вот тоже об этом подумал. Иногда это бывает нужно, а обычно нет, и вот там, где "нет", почему не проверить-то на этапе компиляции, что все "сообщения", которыми обмениваются объекты, имеют смысл для этих объектов? Раньше, помню, начинаешь работать с какой-нибудь библиотекой, функционирующей именно в парадигме обмена сообщениями именно как сообщениями, где всё "связывание" уходит в рантайм - первым делом думаешь: "о, круто!", а по-факту получаешь как бы дополнительный интерпретируемый мини-язык поверх основного компилируемого, и потом с ним горя хапнешь.


  1. checkpoint
    27.03.2024 13:27
    +4

    Обмен сообщениями (message passing) прекрасно реализуется без всякого ООП. Это две ортогональные друг другу концепции, они не мешают и могут взаимно дополнять друг друга.


    1. lorc
      27.03.2024 13:27

      "Обмен сообщениями" в терминологии тех годов - это то что мы сейчас называем "вызов метода".

      В 1960-х никто и не слышал о микросервисах, оркестраторах, асинхронных очередях сообщений, service mesh и другой чертовщине.


      1. checkpoint
        27.03.2024 13:27
        +4

        Концепция "обмена сообщениями" была придумана гораздо раньше чем Вы думаете. Более того, она очень плотно используется в цифровой аппаратуре со времен мэйнфреймов. Т.е. все эти микросервисы - не что иное как давно забытое старое на новый лад. :) Просто г-н Алан Кей выкресталлизовал её в отдельную методологию программирования, вместе с рядом других идей.

        PS: И если я правильно помню, то эти идеи были выражены в языке Smalltalk.


        1. victor_1212
          27.03.2024 13:27

          если я правильно помню, то эти идеи были выражены в языке Smalltalk

          конечно, все это идет от real time и моделирования, чем именно занимался Alan Kay в молодости можно посмотреть например -

          https://worrydream.com/EarlyHistoryOfSmalltalk/

          хотя то что Kay делал было в общем на периферии работ того времени, с опытными людьми он общался, sage и здесь оказал большое влияние, типа сотни людей работали, полезность нечто подобного ООП для real time стала понятно быстро, другое дело что реализовать на ассемблере было трудно, но попытки были, задним числом для real time вероятно это правильный подход, особенно учитывая что все делалось на mainframes, для остального sw возможно ценность ООП не такая высокая, типа с умом надо применять, в том числе С++


    1. nin-jin
      27.03.2024 13:27

      Обмен сообщениями между кем и кем?


      1. checkpoint
        27.03.2024 13:27
        +2

        Между двумя и более сущностями.


        1. nin-jin
          27.03.2024 13:27

          Вот и получаем Сущностно Ориентированное Программированиие.


          1. checkpoint
            27.03.2024 13:27
            +3

            Дак вся идея "программирования" как такового и состоит в том, чтобы правильно выделить в задачи сущности и наладить между ними взаимодействие.


      1. chaetal
        27.03.2024 13:27

        Очевидно: между объектами.


  1. VaVM
    27.03.2024 13:27

    Хотя при обучении ООП часто делается упор на наследование, на самом деле это не фундаментальный атрибут ООП

    да, незнание и непонимание ООП приводит еще и не к таким шедевральным "открытиям".

    Ещё в статье восхищает использование доисторической терминологии "посылка сообщения" вместо современной "вызов метода". Во времена SmallTalk этот термин был вполне правомерным, так как методы в SmallTalk вызывались посылкой объектов-сообщений. Но с тех пор прошло более 50 лет. И ни в каком языке программирования для вызова методов сообщения не посылаются.

    А как длинно, запутанно и с повторениями объясняются простые вещи! Да ещё зачастую неправильно. Полагаю, код, который пишет автор, столь же шедеврален.


    1. orekh
      27.03.2024 13:27
      +1

      Я их не трогал толком, но Elm (язык) и Iced (фреймворк), используемые для построения интерфейса, вроде бы посылают объекты-события. Редкость, конечно, но они существуют.


    1. unreal_undead2
      27.03.2024 13:27
      +2

      использование доисторической терминологии "посылка сообщения" вместо современной "вызов метода"

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

      И ни в каком языке программирования для вызова методов сообщения не посылаются.

      В Objective C используется именно Smalltalk'овский подход; в Swift'е вроде вырезали, но не уверен, что вся ObjC кодовая база в macOS умерла.

      И в любом случае, на мой взгляд, независимо от используемого языка неплохо иметь хотя бы поверхностное представление о разных вариантах реализации ООП - в Smalltalk, C++, Self (хотя вместо него сгодится Javascript), Common Lisp.


      1. Source
        27.03.2024 13:27
        +2

        Посылка сообщений также является основным механизмом в языках на базе виртуальной машины BEAM: Erlang, Elixir, Gleam.

        И да, с вызовами методов тут действительно ничего общего.


      1. geher
        27.03.2024 13:27
        +2

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

        Вызов метода можно реализовать через обиен сообщениями, а обмен сообщениями можно реализовать через вызовы методов. Но это не более чем мелкие технические детали.

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

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

        Классы, инкапсуляция, наследование, полиморфизм, сообщения - это не более чем низкоуровневые абстракции, предназначенные для упрощения воплощения предстввления предметной области в виде взаимодействующих объектов.

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


    1. PrinceKorwin
      27.03.2024 13:27
      +4

      Но с тех пор прошло более 50 лет. И ни в каком языке программирования для вызова методов сообщения не посылаются.

      Вы компетентны во всех современных языках?

      Например Ruby:
      https://apidock.com/ruby/Object/send

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

      Да в Ruby почти вся магия на этом построена. Ruby можно отнести к современным языкам?


    1. arielf
      27.03.2024 13:27
      +1

      Ещё в статье восхищает использование доисторической терминологии "посылка сообщения" вместо современной "вызов метода".

      Ну что за чушь! Посылка сообщений и вызов методов – принципиально разные вещи!

      Сообщение – это объект, состоящий из текстовой строки (имени сообщения) и возможного списка аргументов.

      Метод – это объект, реализующий некоторую функциональность, проще говоря функция, привязанная к объекту.

      Посылка сообщения – это способ коммуникации объектов. Объект, получивший сообщение, сам решает, как ему поступить с ним. Он может (1) ничего не ответить, (2) вызвать метод, соответствующий имени сообщения, (3) выбросить исключение или (4) переслать сообщение иному объекту.

      Вызов метода – это вызов некоторой функции, привязанной к объекту, и передача ей возможных аргументов, вот и всё. Так что вызов метода – это лишь один из многих возможных способов реакции объекта на полученное сообщение.

      Механизм сообщений является неотъемлемой частью ООП, но используется и вне его. Например, все распределённые системы параллельных вычислений (MPI) используют посылку сообщений. Поскольку сообщение – это текстовая строка и список аргументов, его можно послать по сети. Вызвать функцию или метод по сети нельзя (если вы не знали). Межпроцессные коммуникации (IPC) также используют механизм сообщений. Ибо вызвать функцию или метод из иного процесса тоже нельзя.

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

      И ни в каком языке программирования для вызова методов сообщения не посылаются.

      Вы так пишите, словно Smalltalk исчез. Он живёт и используется в промышленном программировании. Не в РФ, конечно. Из более новых языков сообщения используются в Ruby.


  1. accurate_random
    27.03.2024 13:27

    проведу прагматичное исследование ООП

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


  1. diakin
    27.03.2024 13:27

    -Выходит у вас два ООП?
    -Выходит - джва два!


    1. OldNileCrocodile
      27.03.2024 13:27

      Java 2 EE?


  1. CorwinH
    27.03.2024 13:27
    +2

    Есть разные подходы к архитектуре. Спор на тему, какой из них является "правильным ООП", по сути является спором о терминологии, и поэтому бессмысленен.

    Если взять за определение цитату Алана Кея из данной статьи, то получим, что erlang является объектно-ориентированным языком, что не мешает ему в то же время быть функциональным языком. Что касается приведённых в статье плюсов данного подхода, то того же самого можно добиться, используя другие подходы.

    Если взять за определение "инкапсуляция, наследование, полиморфизм", очень популярное на рубеже веков, то этот подход в изначальном виде, практически, не используется. Разберём по пунктам.

    Инкапсуляция

    Кто-то понимает её как сокрытие данных, кто-то как объединение данных и методов в одном объекте. Правы и те, и другие. Её смысл в контроле состояния самим объектом - как и пункт "локальное удержание и защита, сокрытие состояния" в данной статье. То есть, у объекта нет открытых данных, а изменение данных (состояния) идёт только через методы. Но для этого недостаточно заменить "public string Name;" на "public string Name { get; set; }". "Автосвойства" нарушают этот принцип, так как контроль состояния подразумевает включения в метод name_get() валидации. Но это очевидно неудобно, а в сложных случаях и вовсе невозможно. Обычно валидацию выносят в отдельный метод (позволяет, например, собрать полный список ошибок валидации) или даже в отдельный класс (например, чтобы не дублировать код валидации по атрибутам). Инкапсуляция также подразумевает, что объект должен уметь сам себя сохранять и т.п. Это тоже неудобно, так как код сохранения обычно очень похож для разных классов объектов и больше зависит от того, куда сохраняем, чем от того, что сохраняем.

    Наследование

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

    Полиморфизм

    Под полиморфизм в ООП подразумевается полиморфизм подтипов. Между тем в современных объектно-ориентированных языках широко используется обобщённый полиморфизм.

    В итоге, современный подход довольно сильно отличается и от подхода Алана Кея, и от подхода "инкапсуляция, наследование, полиморфизм". И это делает упомянутый выше спор о терминологии ещё более бессмысленным.


    1. Source
      27.03.2024 13:27

      Если взять за определение цитату Алана Кея из данной статьи, то получим, что erlang является объектно-ориентированным языком, что не мешает ему в то же время быть функциональным языком. 

      Всё так. Это вообще лучшее сочетание ООП и ФП:
      ООП на верхнем уровне, а внутри объекта (актора) логика пишется в функциональной парадигме.


    1. victor_1212
      27.03.2024 13:27
      +2

      Если взять за определение цитату Алана Кея из данной статьи

      современный подход довольно сильно отличается и от подхода Алана Кея

      полезно учесть, что данная статья является переводом статьи Dick Dowdell из "Nerd For Tech", если посмотреть его остальные статьи, уровень автора станет понятным,

      (imho) то что пишет Alan Kay стоит читать в оригинале, источников достаточно, про общие принципы например здесь -

      https://worrydream.com/EarlyHistoryOfSmalltalk/

      мне понравилось например это -

      "... final comment. Hardware is really just software crystallized early. It is there to make program schemes run as efficiently as possible. But far too often the hardware has been presented as a given and it is up to software designers to make it appear reasonable. This has caused low-level techniques and excessive optimization to hold back progress in program design. As Bob Barton used to say: "Systems programmers are high priests of a low cult." One way to think about progress in software is that a lot of it has been about finding ways to late-bind, then waging campaigns to convince manufacturers to build the ideas into hardware ...

      A look beyond OOP as we know it today can also be done by thinking about late-binding"


      1. Arlekcangp
        27.03.2024 13:27
        +3

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

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

        Теперь пару слов о "заменителях" ООП: на эту роль натягивают ФП. Но у всех чистых фп языков мало того что будут проблемы с компиляцией под такую архитектуру (здесь больше из-за попытки оперировать структурами только для чтения. Копирование памяти такая архитектура железа тоже не жалует), так ещё если язык типизированный, то там обычно нет достаточно гибких инструментов для позднего связывания. (А если не типизированный - опять же всё те же грабли с быстродействием. Лисп и Схема как пример). ООП-языки во многом научились обходить ограничения, дозируя действительно позднее связывание малыми порциями, там где оно действительно нужно ивырезав начисто сообщения, заменив их встроенными таблицами виртуальных методов. ФП-языкам это только предстоит и на этот раз нужно сделать как-то более изящно, возможно оптимизировав и железо. Интерфейсы у них есть - это алгебраические типы данных, плюс прикреплённые за счёт полиморфизма к ним функции. Остаётся добавить механизм сообщений. Возможно, как это сделано в Erlang, но не абсолютизировать, а только тогда, когда это действительно требуется.


        1. funca
          27.03.2024 13:27

          Примером языков с поздним связыванием являются скриптовые. Для решения проблем с производительностью в них достаточно успешно используется JIT.


        1. victor_1212
          27.03.2024 13:27

          все становится на свое место, если читать оригиналы, и более-менее знать историю :)


  1. pashaspashas
    27.03.2024 13:27

    Автор сформулировал несуществующую проблему и сам путанно и подробно попытался ее распутать. С другой стороны статья полностью соответствует названию.


  1. svischuk
    27.03.2024 13:27
    +2

    Из названия статьи следует, что есть критика ООП, но в статье ни ее, ни ее разбора нет, зато есть накрутка рейтинга


  1. panzerfaust
    27.03.2024 13:27

    Стремно быть человеком, который на полном серьезе живет этими холиварными вопросами. Я предпочитаю относится к этому по-чапаевски (в пелевинском прочтении): мне вообще до звезды, актуален ли ООП. Я писал код, где джавовый ООП работал отлично. Сейчас я пишу код, где вообще никакого ООП нет. Возможно, однажды снова буду писать с ООП. Мне норм.


    1. unreal_undead2
      27.03.2024 13:27

      И вообще "настоящий программист напишет фортрановскую программу на любом языке" )


  1. odisseylm
    27.03.2024 13:27

    Писатели этих статей, как вы уже запарили! :-)

    Вы не правильно используете ООП.
    ООП умер.
    Что не так с ООП?
    И бла-бла... Какая уже по счету статья?

    Я не ищу эти статьи, они сами вылазят в рекомендациях.


  1. dmitryklerik
    27.03.2024 13:27
    +1

    Очень хочется вбросить одну тему для обсуждения и мне кажется тут самое подходящее место:

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

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

    Как вам такое противоречие?


    1. funca
      27.03.2024 13:27

      Разница как между частной собственностью и общественной.


    1. victor_1212
      27.03.2024 13:27

      Очень хочется вбросить одну тему для обсуждения и мне кажется тут самое подходящее место ....

      если уж вбрасывать, лучше подумать над свежей темой - как можно использовать идеи ООП в биоинфоматике, там ситуация примерно как если бы при помощи байтового редактора мы могли менять отдельные байты в файле ОС порядка 2GB и наблюдать что получается, очень слабо представляя и формат файла и систему команд, но понятно что этот формат намного сложнее чего-нибудь типа elf или pe32, грубо говоря нужен ООП язык для описания такой структуры, естественно не только для генома человека, а вообще всего живого до бактерий,

      в самом грубом приближении - основная структурная единица называется геном, сколько их точно в геноме человека неизвестно - 20-100K, такой разброс связан с тем, что далеко не все из них являются активными, типа резервные копии, + далеко не все кодируют протеины, так что есть разные определения, вообще более-менее известно назначение примерно 6К генов, про структуру отдельных генов кое-что известно - в среднем 7-8 пар последовательностей exons - intron, типа работающая часть и разделитель, далее тем кто заинтересуется надо читать статьи и пр.

      зачем это надо, и что уже умеют - к примеру пару недель назад сделали первую пересадку человеку почки от специальной линии свиней с 69 отредактированными генами (для снижения риска отторжения), пока все нормально, если все будет хорошо проблем с донорами + ожидания несколько лет больше не будет, конечно это только самое начало, того что возможно уже в ближайшем будущем,

      если бы был помоложе, серьезно рассмотрел бы возможность перехода в биоинфоматику, там работы хватит лет на 100, но увы 70+, из них 50 в программировании, тем кто думает о смене карьеры - вопрос к размышлению,

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


    1. victor_1212
      27.03.2024 13:27

      ps

      через 15 минут минус в карму, обычное дело для хабр, без разницы конечно :)


    1. snuk182
      27.03.2024 13:27

      создание сильной связи между родителем и наследниками это источник постоянных проблем

      Эээээ, и да и нет. Просто в привычных реализациях этого концепта решили не отделять наследуемые контракты от наследуемой реализации, то есть "я обладаю возможностями родителя = я родитель". Это, уже с точки зрения оббитых за десятилетия углов, концепция дурно пахнущая. С другой стороны, есть "внедрение вместо наследования", где все проблемы выворачиваются наизнанку. Пока что лучшая из видимых мною реализаций ненавязчивого наследования - Golang.


  1. DonJovi
    27.03.2024 13:27
    +1

    ООП еще как актуально, учась в магистратуре на зимней сессии сдавал экзамен по ОПП, так что актуальность данного направления программирования в стенах вузов будет еще как минимум на лет 5-10))))