Да здравствует объектно-ориентированное программирование!

(Это ответ на Прощай, объектно-ориентированное программирование.)

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

И, по иронии судьбы, ООП теперь превратилось во что-то более близкое к тому, чем оно было изначально. До появления всех этих статически типизированных объектно-ориентированных языков, вдохновленных C++, существовали такие языки, как Smalltalk, Self, и объектные системы, такие как CLOS. CLOS, например, вообще не применяла инкапсуляцию; у него также была множественная диспетчеризация (например, множественные методы Clojure). У Self даже не было классов (JavaScript, конечно, был сильно вдохновлен им). Все они были «объектно-ориентированными», хотя и не были похожи на C++, C# или Java.

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

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

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

Опять же, по иронии судьбы, объекты сегодня лучше всего представлены языками, которые утверждают, что НЕ являются объектно-ориентированными: Go (полиморфизм через интерфейсы), Rust (дженерики, трейты), Clojure/Elixir (протоколы, мультидиспетчеризация), JavaScript (прототипы), Swift (возможно, лучший пример современного языка в традициях SmallTalk) и даже Haskell* вдохновлены объектной ориентацией.

Но если оно ходит как ООП и крякает как ООП, это все равно ООП, как бы мы это ни называли.

* Ну, классы типов. Но если вы не покупаете это, см. https://www.well-typed.com/blog/2018/03/oop-in-haskell.