Java и ООП: путешествие туда и обратно

от автора

Недавно на подкасте Spring АйО мы обсуждали новые свитчи в Джаве — с паттерн-матчингом и деструктуризацией. Я тогда ещё выразил мнение, что всё это неправославно, по-зумерски и отход от принципов ООП.

Не от инкапсуляции, полиморфизма и наследования, а вообще от подхода. Новые свитчи будут провоцировать разработчиков писать код по-новому, а не так, как завещали нам наши далёкие предки. С нарушением традиций, норм и устоев. Как учит Кейси Муратори, если вы понимаете о ком я.

Но какие они вообще были эти устои? Каким было ООП, когда всё только началось и чем это отличается от свитчей, до которых мы в конце концов докатились?

Источник ООП

В Джаву ООП пришло из C++. В С++ ООП попало от Бярны (наверное, это наиболее правильное произношение) Страуструпа, по совместительству автора языка.

А сам Страуструп откуда почерпнул идеи ООП? По его собственному признанию, он взял их из языка программирования Simula, предназначенного для разработки симуляции сложных систем.

Этот язык разработали в норвежской лаборатории Кристен Найгард и Оле-Йохан Даль. В 1967 году между прочим. Наверное, 1967 год это достаточно давно, и можно смело считать, что ООП впервые появилось в Simula?

А вот и нет. При разработке Simula норвежцы использовали идеи Энтони Хоара, также известного, как автора алгоритма быстрой сортировки.

Структуры с дискриминатором

Хоар хотел сделать что-то вроде discriminated unions. То есть структуры, в которых могут быть разные наборы полей, в зависимости от типа. А чтобы разработчик не допустил ошибку и не попробовал получить из структуры поле, которого там нет, в структуре всегда было поле, где был указан её тип. То есть был дискриминатор.

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

consider e when constant then ...            when variable then ...            when pair then ... 

Ничего не напоминает? Это же практически один в один switch c паттерн матчингом из новой Джавы!

switch (e) {     case Constant c:         System.out.println(c.value());         break;     case Pair p:         System.out.println(p.left() + ", " + p.right());         break;     case Variable v:         System.out.println(v.value());         break; }

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

Скрытый текст
public class Main {     static void print(Expression e) {         switch (e) {             case Constant c:                 System.out.println(c.value());                 break;             case Pair p:                 System.out.println(p.left() + ", " + p.right());                 break;             case Variable v:                 System.out.println(v.value());                 break;         }     }      public static void main(String[] args) {         print(new ConstantImpl(123));     } }  sealed interface Expression         permits Constant, Variable, Pair { }  sealed interface Constant         extends Expression         permits ConstantImpl {     int value(); }  sealed interface Variable         extends Expression         permits VariableImpl {     int value();     void set(int newValue); }  sealed interface Pair         extends Expression         permits PairImpl {     int left();     int right(); }  record ConstantImpl(int value)         implements Constant { }  final class VariableImpl         implements Variable {      private int value;      @Override     public int value() {         return value;     }      @Override     public void set(int newValue) {         value = newValue;      } }  record PairImpl(int left, int right)         implements Pair { } 

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

И в Simula эта фича тоже была, только за неё отвечало ключевое слово inspect.

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

Вот так вот. Энтони Хоар дал, Бьярна Страуструп взял.

switch с паттерн-матчингом – это и есть ортодоксальное ООП!

Я это всё к чему. Как выясняется, идея свитчей по типам структур с последующим доступом к их полям была в ООП с самого начала! Просто она была утеряна при переходе от Simula к C++.

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

Посмотрите выступление Кейси Муратори!

Возможно, вам интересно, откуда я знаю такие интересные и захватывающие факты из истории языков программирования. Тут могу вас обрадовать. Всё это и намного больше можно узнать из недавно опубликованного на Ютубе доклада Кейси Муратори. Того самого Кейси Муратори, который давно уже ведёт борьбу против ООП, Solid, а также всего что с ними связано. И, кажется, ведёт по очкам ))) . Держите линк!

P. S.

Идея свитчей по типу, похоже, принадлежит именно Хоару, но вот сама идея типизированных структур из N полей заимствована им у Дагласа Росса в Mit Servomechanisms laboratory, предположительно, в середине пятидесятых годов. Росс даже не называл эти структуры структурами, у него для них было специальное слово — плекс. В этих самых плексах уже были поля, и аналоги виртуальных функций. Только наследования тогда ещё, кажется, не было.

В середине пятидесятых! 70 лет назад!


Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано


ссылка на оригинал статьи https://habr.com/ru/articles/934514/


Комментарии

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

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