в результате какой идеологии возникло объектно ориентированное программирование
Коротко об истории объектно-ориентированного программирования
Эта статья была написана под влиянием впечатлений, полученных автором в ходе одной дискуссии на Хабре, и представляет небольшую серию переводов материалов из свободных источников об истории объектно-ориентированного программирования, основным из которых является Википедия, плюс абсолютно предвзятые выводы автора из прочитанного материала.
Если вам интересно узнать, какой язык в действительности был первым ООП-языком на свете, могут ли Java и C# называться чистыми ООП-языками, а также проникнуться некоторыми другими деталями, приглашаю вас под кат…
Сначала перевод об истории ООП из Википедии:
«Термины «объектно-» и «ориентированный» в современном смысле этих слов появились в MIT в конце 1950 начале 1960 годов. В среде специалистов по искусственному интеллекту термин «объект» мог относиться к идентифицированным элементам (атомы Lisp) со свойствами (атрибутами). Алан Кэй позже писал, что понимание внутреннего устройства Лиспа оказало серьезное влияние на его мышление в 1966 г. Другим ранним примером ООП в MIT был Sketchpad созданный Иваном Сазерлендом в 1960-61. В глоссарии подготовленного в 1963 г. технического отчета, основанного на его диссертации о Sketchpad, Сазерленд определяет понятия «объект» и «экземпляр» с концепцией классов на основе «мастера» или «определения», хотя все эти термины относились к графическому представлению объектов [вкратце, в Sketchpad было основное изображение, на основе которого строились копии. При изменении основного – копии тоже менялись. Прим. пер.].
В ранней MIT-версии ALGOL AED-0 структуры данных («плексы» на диалекте Алгола) напрямую были связаны с процедурами, которые впоследствии были названы сообщениями, методами или функциями-членами.
Объекты, как формализованный концепт появились в программировании в 1960-х в Simula 67, модернизированной версии Simula I, языка программирования, ориентированного на дискретно-событийное моделирование. Авторы Simula — Оле-Йохан Даль и Кристен Нюгорд из Норвежского компьютерного центра в Осло. Simula разрабатывалась под влиянием SIMSCRIPT и предложенной Чарльзом Хоаром концепцией записей-классов. Simula включала в себя понятие классов и экземпляров (или объектов), а также подклассов, виртуальных методов, сопрограмм и дискретно-событийное моделирование как часть собственной парадигмы программирования. В языке использовался автоматический сборщик мусора, который был изобретен ранее для функционального языка Lisp. Simula использовалась тогда преимущественно для физического моделирования. Идеи Simula оказали серьезное влияние на более поздние языки, такие как Smalltalk, варианты Lisp (CLOS), Object Pascal, и C++.
Язык Smalltalk, который был изобретен в компании Xerox PARC Аланом Кэем (Alan Kay) и некоторыми другими учеными, фактически навязывал использование «объектов» и «сообщений» как базиса для вычислений. Создателей Smalltalk вдохновляли некоторые идеи Simula, но Smalltalk разрабатывался как полностью динамичная система, в которой классы могут создаваться и изменяться динамически, а не только статически как в Simula. Smalltalk и ООП с его помощью были представлены широкой аудитории в журнале Byte magazine в августе 1981.
В 1970-х Smalltalk Кэя сподвиг сообщество Lisp внедрить в язык объектно-ориентированные техники, которые были представлены разработчикам с помощью Lisp машины.
Эксперименты с различными расширениями Lisp в конечном итоге привели к созданию Common Lisp Object System (CLOS, части первого стандартизованного объектно-ориентированного языка, ANSI Common Lisp), который органично включал в себя как функциональное, так и объектно-ориентированное программирование и позволял расширять себя с помощью протокола Meta-object protocol. В 1980 было несколько попыток дизайна архитектур процессоров, которые включали бы в себя аппаратную поддержку работы с объектами в памяти, но все они были безуспешны. В качестве примеров можно привести Intel iAPX 432 и Linn Smart Rekursiv.
Объектно-ориентированное программирование развилось в доминирующую методологию программирования в начале и середине 1990 годов, когда стали широко доступны поддерживающие ее языки программирования, такие как Visual FoxPro 3.0, C++, и Delphi. Доминирование этой системы поддерживалось ростом популярности графических интерфейсов пользователя, которые основывались на техниках ООП. Пример тесной связи между динамической библиотекой GUI и объектно-ориентированного языка программирования можно найти посмотрев на фреймворк Cocoa на Mac OS X, который был написан на Objective-C, объектно-ориентированом расширении к С, основанном на Smalltalk с поддержкой динамических сообщений. Инструментарии ООП повлияли на популярность событийно-ориентированного программирования (хотя, эта концепция не ограничивается одним ООП). Некоторые даже думали, что кажущаяся или реальная связь с графическими интерфейсами – это то, что вынесло ООП на передний план технологий.
В ETH Zürich, Никлаус Вирт и его коллеги тоже исследовали такие предметы, как абстрация данных и модульное программирование, хотя эти подходы широко использовались и в 60-х и ранее. Modula-2 вышедшая в 1978 включала оба эти подхода, а ее последователь Oberon имел собственный подход к объктно-ориентированности, классам и прочему, непохожий на подход Smalltalk и совсем не похожий на подход C++.
Возможности ООП добавлялись во многие языки того времени, включая Ada, BASIC, Fortran, Pascal и другие. Их добавление в языки, изначально не разрабатывавшиеся для поддержки ООП часто приводило к проблемам с совместимостью и поддержкой кода.
Теперь перевод небольшой части статьи «Как начиналось объектно-ориентированное программирование» за авторством Оле-Йохана Даля и Кристена Нюгорда.
«SIMULA I (1962-65) и Simula 67 (1967) — два первых объектно-ориентированных языка программирования. Simula 67 включала в себя большую часть концепций объектно-ориентированного программирования: классы и объекты, подклассы (наследование), виртуальные функции, безопасные ссылки и механизмы, позволяющие внести в программу коллекцию программных структур, описанных общим заголовком класса (префиксные блоки).
Алан Кэй из Xerox PARC использовал Simula как платформу для его разработки Smalltalk (первых версий языка в 1970-х), расширяя объектно-ориентированное программирование с помощью интеграции пользовательского интерфейса и интерактивного исполнения. Бьерн Страусструпп начал разработку C++ (в 1980-х) by привнеся основные концепции Simula в С.»
Теперь небольшое обобщение и заключение.
Как видите, получается, что первым ООП языком была Simula. Но первым «чистым» ООП языком был именно Smalltalk. «Чистым» иногда называют ООП язык, все типы которого являются или могут быть прозрачно представленными классами. В этом смысле Java чистым ООП языком стала только в версии 5, когда появилась возможность Autoboxing. C#, если я правильно понимаю, был чистым ООП языком с самого начала. Предлагаю в комментариях поломать копья на темы вроде «А в C# есть неуправляемые указатели, которые не могут быть представлены объектами», «А вообще чистым ООП языком может считаться только Smalltalk, в котором объектами представлено все, вплоть до блоков самой программы, ну или, в крайнем случае, Ruby» и «Чистый – значит, медленный. Ишь чего удумали, int объектом представлять!»
Некоторое время назад один странный хабраюзер заявил в одном из комментариев, что ООП изобрел Алан Кэй, что в чистом ООП нет наследования, что Java и C# по мнению автора термина «ООП» Алана Кэя ООП языками не являются и что Гослинг с Липпертом имеют… гм… проблемы, поскольку совершенно неверно считают, что изобретенные ими языки являются нормальными объектно-ориентированными.
От такой чудовищной чуши у меня немедленно опухли все мои брови я слегка озадачился и полез в гугл за аргументами, намереваясь вынырнуть оттуда через десять минут с кучей фактов. Оказывается, подобные опасные заблуждения точки зрения все же разделяются, пусть и меньшинством читателей. Поэтому я хотел бы привести свою точку зрения на этот счет.
Объектно-ориентированное программирование – парадигма, научный подход к программированию, который разрабатывался не в вакууме, а большой группой ученых. Вклад Кэя в ООП неоценим, но говорить, что ООП – целиком и полностью его изобретение будет несправедливо по отношению ко многим другим ученым, работавшим как вместе с ним, так и отдельно. Кэй действительно когда-то говорил, “I didn’t like the way Simula I or Simula 67 did inheritance (though I thought Nygaard and Dahl were just tremendous thinkers and designers). So I decided to leave out inheritance as a built-in feature until I understood it better.” Как вы понимаете, монополия на изобретение ООП им не заявлялась.
Говорить, что в ООП нет наследования (и всяких прочих современных штучек) и что те, кто его туда привнес извратили смысл и суть ООП, это все равно, что говорить, что геометрия Лобачевского извратила геометрию, изобретенную Евклидом и ее срочно нужно переименовать в «шарометрию» или «гиперболометрию», чтобы грязные руки неофитов не смели касаться святого. Геометрия Римана – вообще тогда от сатаны, а бозонную струнную теорию нельзя преподавать в университетах потому, что это не то, что описывал Габриэле Венециано и его коллеги.
Если вы не согласны, приглашаю продолжить дискуссию в комментах.
Для чего придумали объектно-ориентированное программирование
Объектно-ориентированное программирование стало неотъемлемой частью разработки программного обеспечения. Благодаря языкам программирования, использующим основные идеи и принципы концепции ООП, можно разрабатывать программы для любой платформы, в том числе приложения для мобильных устройств.
Если в традиционном функциональном программировании, элементы кода рассматриваются как точные математические функции, предотвращающие воздействие на другие элементы и исключающие побочные эффекты, то объектно-ориентированное программирование представляет собой совершенной иной подход к решению тех же задач. При использовании ООП разработка программы начинается не с написания функций, а с создания классов, в которых хранятся данные и переменные. Объекты становятся автономными экземплярами этих классов, и за счет разнообразия вариантов их взаимодействия возможности использования программы становятся практически неограниченными.
История развития
Основа ООП была заложена в начале 1960-х годов. Прорыв в использовании экземпляров и объектов был достигнут в MIT с PDP-1, и первым языком программирования для работы с объектами стал Simula 67. Он был разработан Кристен Найгаард и Оле-Джохан Даль в Норвегии с целью создания симуляторов. Они работали над симуляциями взрыва кораблей и поняли, что могут сгруппировать корабли в различные категории. Каждому типу судна было решено присвоить свой собственный класс, который должен содержать в себе набор уникальных характеристик и данных. Таким образом, Simula не только ввела понятие класса, но и представила рабочую модель.
Термин «объектно-ориентированное программирование» был впервые использован Xerox PARC в языке программирования Smalltalk. Понятие ООП использовалось для обозначения процесса использования объектов в качестве основы для расчетов. Команда разработчиков была вдохновлена проектом Simula 67, но они спроектировали свой язык так, чтобы он был динамичным. В Smalltalk объекты могут быть изменены, созданы или удалены, что отличает его от статических систем, которые обычно используются. Этот язык программирования также был первым, использовавшим концепцию наследования. Именно эта особенность позволила Smalltalk превзойти как Simula 67, так и аналоговые системы программирования.
Simula 67 стала новаторской системой, которая впоследствии стала основой для создания большого количества других языков программирования, в том числе Pascal и Lisp. В 1980-х годах объектно-ориентированное программирование приобрело огромную популярность, и основным фактором в этом стало появление языка С++. Концепция ООП также имела важное значение для разработки графических пользовательских интерфейсов. В качестве одного из самых ярких примеров можно привести структуру Cocoa, существующую в Mac OS X.
Принципы
Основная идея ООП заключается в том, что вместо написания программы, вы создаете класс, представляющий собой своего рода шаблон, содержащий переменные и функции. Объекты являются автономными экземплярами этого класса, и вы можете заставить их взаимодействовать между собой как угодно.
В основе концепции объектно-ориентированного программирования лежат несколько базовых принципов:
Ключевые преимущества
Основным достоинством ООП является то, что данная концепция позволяет значительно ускорить разработку новых программ и приложений, разделив общий объем работы между несколькими независимыми программистами или группами сотрудников. Код строится таким образом, что его отдельные логические блоки работают изолированно друг от друга и не могут помешать выполнению других функций.
Среди прочих аргументов в пользу использования объектно-ориентированного программирования можно выделить такие:
Объектно-ориентированные языки программирования поставляются с богатыми библиотеками объектов, а код, разработанный в ходе реализации проекта, также может быть повторно использован в будущем при создании других программ. Используя готовые библиотеки, вы можете еще больше ускорить процесс разработки, адаптируя и модифицируя для своих проектов уже существующие рабочие решения. Это особенно полезно при разработке графических интерфейсов пользователя. Поскольку объектные библиотеки содержат много полезных функций, разработчикам программного обеспечения не нужно “изобретать велосипед” так часто, что дает возможность максимально сосредоточиться на создании новой программы.
Забытая история ООП
Большинство парадигм программирования, которые мы используем сегодня, были впервые математически изучены в 1930-х годах с использованием идей лямбда-исчисления и машины Тьюринга, которые представляют собой варианты модели универсальных вычислений (это формализованные системы, которые могут выполнять вычисления общего назначения). Тезис Чёрча-Тьюринга показал, что лямбда-исчисление и машины Тьюринга функционально эквивалентны. А именно, речь идёт о том, что всё, что можно вычислить с использованием машины Тьюринга, можно вычислить и с использованием лямбда-исчисления, и наоборот.
Есть распространённое заблуждение, в соответствии с которым машины Тьюринга могут вычислить всё, поддающееся вычислению. Существуют классы проблем (например — проблема остановки), которые могут быть вычислимыми с использованием машин Тьюринга лишь для некоторых случаев. Когда в этом тексте используется слово «вычислимо», имеется в виду «вычислимо машиной Тьюринга».
Лямбда-исчисление демонстрирует подход применения функций к вычислениям по принципу «сверху вниз». А ленточная машина Тьюринга представляет императивный (пошаговый) подход к вычислениям, реализуемый по принципу «снизу вверх».
Низкоуровневые языки программирования, вроде машинного кода или ассемблера, появились в 1940-е, а, к концу 1950-х, возникли первые популярные высокоуровневые языки, которые реализовали и функциональный и императивный подходы. Так, диалекты языка Lisp до сих пор широко используются, среди них можно отметить Clojure, Scheme, AutoLisp и так далее. В пятидесятых появились и такие языки, как FORTRAN и COBOL. Они являются примерами императивных высокоуровневых языков, которые всё ещё живы. Хотя надо отметить, что языки семейства C, в большинстве сфер, заменили и COBOL, и FORTRAN.
Корни императивного и функционального программирования лежат в формальной математике вычислений, они появились раньше цифровых компьютеров. Объектно-ориентированное программирование, или ООП (Object Oriented Programming, OOP), пришло позже, оно берёт начало в революции структурного программирования, которая происходила в шестидесятых-семидесятых годах прошлого века.
Первый известный мне объект был использован Айвеном Сазерлендом в его судьбоносном приложении Sketchpad, созданном между 1961 и 1962, описанном им в этой работе в 1963 году. Объекты представляли собой графические знаки, выводимые на экране осциллографа (возможно это — первый в истории случай использования графического компьютерного монитора), и поддерживающие наследование через динамических делегатов, которые Айвен Сазерленд назвал в своей работе «мастер-объектами» (masters). Любой объект мог стать мастер-объектом, дополнительные экземпляры объекта были названы «реализациями» (occurrences). Это сделало систему Sketchpad обладателем первых из известных языков программирования, который реализовал прототипное наследование.
Первым языком программирования, широко известным как «объектно-ориентированный», был язык Simula, спецификации которого были разработаны в 1965 году. Как и Sketchpad, Silmula предусматривал работу с объектами, но также включал в себя классы, наследование, основанное на классах, подклассы, и виртуальные методы.
Виртуальным методом называется метод, определённый в классе, который предназначен для того, чтобы подклассы его переопределяли. Виртуальные методы позволяют программам вызывать методы, которые могут не существовать на момент компиляции кода, благодаря задействованию динамической диспетчеризации для определения того, какой конкретный метод нужно вызывать во время выполнения программы. JavaScript имеет динамические типы и использует цепочку делегирования для определения того, какой метод нужно вызвать.В результате, этот язык не нуждается в представлении концепции виртуальных методов программистам. Другими словами, все методы в JavaScript используют диспетчеризацию во время выполнения программы, в результате методы в JavaScript не нужно объявлять как «виртуальные» для обеспечения поддержки этой возможности.
Мнение отца ООП об ООП
«Я придумал термин «объектно-ориентированный», и могу сказать, что я не имел в виду С++». Алан Кэй, конференция OOPSLA, 1997.
Алан Кэй придумал термин «объектно-ориентированное программирование», имея в виду язык программирования Smalltalk (1972). Этот язык разработали Алан Кэй, Дэн Инглз и другие сотрудники научно-исследовательского центра Xerox PARC в рамках проекта по созданию устройства Dynabook. Язык Smalltalk был более объектно-ориентированным, чем Simula. В Smalltalk всё является объектом, включая классы, целые числа и блоки (замыкания). Первоначальная реализация языка, Smalltalk-72, не имела возможностей создания подклассов. Эта возможность появилась в Smalltalk-76.
В то время, как Smalltalk поддерживал классы, и, в итоге, создание подклассов, в Smalltalk эти идеи не ставились во главу угла. Это был функциональный язык, на который Lisp повлиял так же сильно, как Simula. По мнению Алана Кэя, отношение к классам как к механизму повторного использования кода — это ошибка. Индустрия программирования уделяет огромное внимание созданию подклассов, отвлекаясь от настоящих преимуществ объектно-ориентированного программирования.
У JavaScript и Smalltalk много общего. Я сказал бы, что JavaScript — это месть Smalltalk миру за неправильное понимает концепции ООП. Оба эти языка поддерживают следующие возможности:
В переписке по электронной почте 2003-года Алан Кэй уточнил то, что он имел в виду, когда называл Smalltalk «объектно-ориентированным языком».
«ООП для меня означает лишь обмен сообщениями, локальное сохранение, и защита, и скрытие состояния, и крайне позднее связывание». Алан Кэй
Другими словами, в соответствии с идеями Алана Кэя, самыми важными ингредиентами ООП являются следующие:
Сущность ООП
Комбинация передачи сообщений и инкапсуляции служит нескольким важным целям:
«Я понял, что метафора клетки или компьютера поможет избавиться от данных[. ]». Алан Кэй
Говоря «поможет избавиться от данных», Алан Кэй, конечно, знал о проблемах, вызванных разделяемым мутабельным состоянием, и о сильной связанности, причиной которой является общий доступ к данным. Сегодня эти темы у всех на слуху. Но в конце 1960-х программисты ARPANET были недовольны необходимостью выбирать представление модели данных для своих программ до начала разработки программ. Разработчики хотели уйти от этой практики, так как, заранее загоняя себя в рамки, определяемые представлением данных, сложнее изменить что-то в будущем.
Проблема заключалась в том, что разные способы представления данных требовали, для доступа к ним, разного кода и разного синтаксиса в используемых в некий момент времени языках программирования. Святым Граалем здесь был бы универсальный способ для доступа к данным и для управления ими. Если все данные выглядели бы для программы одинаково, это решило бы множество проблем разработчиков, касающихся развития и сопровождения программ.
Алан Кэй пытался «избавиться» от идеи, в соответствие с которой данные и программы были, в каком-то смысле, самостоятельными сущностями. Они не рассматриваются таковыми в List или в Smalltalk. Тут нет разделения между тем, что можно делать с данными (со значениями, переменными, структурами данных, и так далее) и программными конструкциями вроде функций. Функции — это «граждане первого класса», а программам разрешено меняться во время их выполнения. Другими словами, в Smalltalk к данным нет особого, привилегированного отношения.
Алан Кэй, кроме того, рассматривал объекты как алгебраические структуры, что давало определённые, математически доказуемые, гарантии их поведения.
«Моё математическое образование позволило мне понять, что каждый объект может иметь несколько алгебраических моделей, связанных с ним, что могут быть целые группы подобных моделей, и что они могут быть очень и очень полезными». Алан Кэй
Было доказано, что так оно и есть, и это сформировало базу для объектов, таких, как промисы и линзы, причём, и на то и на другое оказала влияние теория категорий.
Алгебраическая природа того, как Алан Кэй видел объекты, позволила бы объектам обеспечить формальную верификацию, детерминистическое поведение, улучшило бы тестируемость, так как алгебраические модели — это, в сущности, операции, которые подчиняются нескольким правилам в форме уравнений.
На жаргоне программистов «алгебраические модели» — это абстракции, созданные из функций (операций), которым сопутствуют определённые правила, приводимые в жизнь модульными тестами, которые эти функции должны пройти (аксиомы, уравнения).
Эти идеи были на десятилетия забыты в большинство объектно-ориентированных языков семейства C, включая C++, Java, C# и так далее. Но эти идеи начинают поиски обратного пути, в свежие версии наиболее широко используемых объектно-ориентированных языков.
По этому поводу кто-то может сказать, что мир программирования открывает заново преимущества функционального программирования, и привести рациональные доводы в контексте объектно-ориентированных языков.
Как JavaScript и Smalltalk ранее, большинство современных объектно-ориентированных языков становится всё более и более «мультипарадигменными». Нет причины выбирать между функциональным программированием и ООП. Когда мы смотрим на историческую сущность каждого из этих подходов, они выглядят не только как совместимые, но и как дополняющие друг друга идеи.
Что, в соответствии с мыслями Алана Кэя, является самым главным в ООП?
Вот пара примеров на JavaScript:
Взаимоотношения универсальных типов может быть сложно правильно и полно выразить в языках вроде TypeScript, но это очень просто сделать в системе типов Хиндли-Милнера, применяемой в Haskell, поддерживающей типы высших родов (типы типов).
Большинство систем типов предусматривают слишком сильные ограничения для того, чтобы позволить свободное выражение динамических и функциональных идей, таких, как композиция функций, свободная композиция объектов, расширение объектов во время выполнения программы, применение комбинаторов, линз и так далее. Другими словами? статические типы часто усложняют написание ПО с использованием методов компоновки.
Если ваша система типов отличается слишком большим числом ограничений (как в TypeScript или в Java), то вы, для достижения тех же целей, вынуждены писать более сложный код, чем при использовании языков с более свободным подходом к типизации. Это не значит, что использование статических типов — это неудачная идея, или что все реализации статических типов характеризуются одинаковыми ограничениями. Я, например, сталкивался с гораздо меньшим количеством проблем, работая с системой типов Haskell.
Если вы — фанат статических типов и не против ограничений — желаю вам семь футов под килем. Но если вы обнаружили, что некоторые из высказанных здесь идей сложно реализуемы из-за того, что непросто типизировать функции, полученные путём композиции других функций, и составные алгебраические структуры, тогда вините систему типов а не идеи. Водителям нравятся удобства, которые дают им рамные внедорожники, но никто не жалуется на то, что они не летают. Для полёта нужно транспортное средство, у которого больше степеней свободы.
Если ограничения упрощают ваш код — это замечательно! Но если ограничения принуждают вас к написанию более сложного кода, то, возможно, что-то не так с этими ограничениями.
Что такое «объект»?
Слово «объект», со временем, приобрело множество побочных оттенков значения. То, что мы называем «объектами» в JavaScript — это просто составные типы данных, без намёков на что-то из программирования, основанного на классах, или на идеи Алана Кэя о передаче сообщений.
В JavaScript эти объекты могут поддерживать, и часто поддерживают, инкапсуляцию, передачу сообщений, разделения поведения через методы, даже полиморфизм с использованием подклассов (хотя и с использованием цепочки делегирования, а не диспетчеризации, основанной на типе).
Алан Кэй хотел избавиться от различия между программой и её данными. JavaScript, в некоторой степени, достигает этой цели, помещая методы объектов туда же, где находятся свойства, хранящие данные. Любому свойству, например, можно назначить любую функцию. Конструировать поведение объекта можно динамически и менять смысловое содержание объекта во время выполнения программы.
Объект — это всего лишь составная структура данных, и ему не нужно ничего особенного для того, чтобы считаться объектом. Однако программирование с использованием объектов не ведёт к тому, что такой код оказывается «объектно-ориентированным», так же, как использование функций не делает код «функциональным».
ООП больше не является настоящим ООП
Так как понятие «объект» в современных языках программирования означает гораздо меньше, чем означало для Алана Кэя, я использую слово «компонент» вместо слова «объект» для описания правил настоящего ООП. Многими объектами владеет и управляет напрямую некий сторонний по отношению к ним код на JavaScript, но компоненты должны инкапсулировать собственное состояние и контролировать его.
Вот что такое настоящее ООП:
Манипулирование объектами в JavaScript или использование наследования, основанного на классах, не означает, что некто занимается ООП-программированием. А вот использование компонентов такими способами — означает. Но от устоявшихся представлений о терминах очень сложно отвязаться, поэтому, возможно, нам надо оставить термин «ООП» и назвать то, для чего используются вышеописанные «компоненты», «программированием, ориентированным на сообщения» (Message Oriented Programming, MOP)? Ниже мы будем пользоваться термином «MOP», говоря о программировании, ориентированном на сообщения.
По случайности, английское слово «mop» переводится как «швабра», а их, как известно, используют для наведения порядка.
На что похоже хорошее MOP?
В большинстве современных программ имеется некий пользовательский интерфейс (User Interface, UI), ответственный за взаимодействие с пользователем, некий код, занятый управлением состоянием приложения (данными пользователя), и код, работающий с системой или отвечающий за обмен данными с сетью.
Для обеспечения работы каждой из этих систем могут понадобиться долгоживующие процессы, такие, как прослушиватели событий. Тут понадобится и состояние приложения — для хранения чего-то вроде сведений о сетевых соединениях, о положении дел с элементами управления интерфейса и о самом приложении.
Между тем, компонент, отвечающий за сетевые соединения, может наблюдать за подключением пользователя к другому компьютеру в сети, прослушивать сообщения и диспетчеризовать обновлённое представление состояния для сохранения его на удалённой машине. Подобный компонент отвечает за работу с сетевыми механизмами, знает о том, работает соединение или нет, и так далее.
Подобные системы приложения не должны знать подробности о других его частях. Они должны заботиться лишь о решении собственных задач. Компоненты системы можно разбирать и собирать как конструктор. Они реализуют стандартизированные интерфейсы, а это значит, что они могут взаимодействовать друг с другом. До тех пор, пока общеизвестные требования к интерфейсу компонентов выполняются, такие компоненты можно заменять другими, с такими же интерфейсами, но делающими то же самое по-другому, или выполняющими, принимая те же сообщения, нечто совершенно иное. Менять одни компоненты на другие можно даже во время выполнения программы — это её работу не нарушит.
Компоненты некоей программной системы даже не должны находиться на одном и том же компьютере. Система может быть децентрализованной. Сетевое хранилище может разместить данные в децентрализованной системе хранения данных вроде IPFS, в результате пользователь оказывается независимым от исправности некоей конкретной машины, которая обеспечивает сохранность его данных. При таком подходе данные оказываются надёжно сохранёнными и защищёнными от злоумышленников.
ООП, отчасти, появилось под воздействием идей ARPANET, а одной из целей этого проекта было создание децентрализованной сети, которая будет устойчива к атакам наподобие ядерного удара.
Хорошая MOP-система может характеризоваться похожим уровнем устойчивости, используя компоненты, которые поддерживают «горячую замену» во время работы приложения. Она сможет продолжить функционирование в том случае, если пользователь работает с ней с сотового телефона и оказался вне зоны действия сети из-за того, что въехал в туннель. Если ураган нарушил электропитание одного из дата-центров, в котором расположены её серверы, она тоже продолжит функционировать.
Настало время, чтобы мир программного обеспечения освободился бы от неудачного эксперимента с наследованием, основанным на классах, и принял бы математические и научные принципы, которые стояли у истоков ООП.
Пришло время, чтобы мы, разработчики, создавали бы более гибкие, устойчивые, красивые программы, используя гармоничное сочетание MOP и функционального программирования.
Кстати, акроним «MOP» уже используется, описывая «программирование, ориентированное на мониторинг» (Monitoring Oriented Programming), но эта концепция, в отличие от ООП, просто тихо исчезнет.
Поэтому не расстраивайтесь, если термин «MOP» не выглядит словом из жаргона программистов. Просто приведите своё ООП в порядок с помощью рассмотренных выше принципов MOP.
