Noobo Droid
ООП. От создания до сегодняшних дней
Решил написать заметку по мотивам полезнейшего треда, который стал для меня-вайтишника интереснейшим открытием и попробовать разложить по полочкам прошедшую через меня информацию. Не претендую ни в коем случае на особое авторство, цель заметки собрать воедино информацию по нескольким источникам, чтобы разобраться в ООП тогдашнем и ООП сегодняшнем, пройдя небольшой исторический экскурс.
Начну сразу с итоговой развязки, чтобы проще было разобраться. Понятие ООП имеет две трактовки, то есть две школы. Первая школа - Алана Кэя, ее и планирую рассмотреть подробно. Вторая - Грэди Буча, ООП в том виде, в каком мы его знаем сегодня.
ООП Алана Кэя
Первым объектно-ориентированным языком является Simula. Первая версия языка вышла в 1962 году. Simula 67, соответственно, в 1967 году. Язык предусматривал работу с объектами и включал в себя:
- классы;
- наследование (основанное на классах);
- подклассы;
- виртуальные методы.
В 1972 году Алан Кэй, Дэн Инглз и другие сотрудники научно-исследовательского центра Xerox PARC разработали язык Smalltalk, который основан на языке Simula. И вот это как раз тот язык, по которому Алан Кэй придумал первую и свою трактовку термина «объектно-ориентированное программирование», ведь и сам Smalltalk был более объектно-ориентированным. В Smalltalk всё является объектом, включая классы, целые числа и блоки (замыкания).
И тут сейчас важно приостановиться и подумать: не смотря на то, что Алан Кэй создал с командой язык, концепция которого сводится к созданию объектов, сама идея являлась в том, что нужно акцентироваться не на возможности создания объектов, а на обмене сообщениями между объектами, что подтверждается словами самого Алана:
ООП для меня — только сообщения, локальное удержание и защита, скрытое состояние и — в последствии — связывание всего
На этом моменте во время написания заметки я словил deadlock сильно завис, к счастью, мне помог Кирилл. А застрял на самом понимании концепции обмена сообщениями, поэтому немного подробнее, что под ней подразумевается.
Рассмотрим вызов функций на примере сравнения с языком C++. В Smalltalk мы можем отправить любое сообщение любому объекту и компилятор не накладывает на это ограничений, когда в C++ мы можем вызывать только те функции, о которых компилятор знает.
И теперь подробнее о тех самых виртуальных методах, перечисленных выше, что есть, как в языке Simula, так и Smalltalk: виртуальные методы - методы, определённые в классе, который предназначен для того, чтобы подклассы его переопределяли. Методы могут не существовать на момент компиляции кода и благодаря задействованию динамической диспетчеризации могут указать какой конкретный метод нужно вызывать во время выполнения программы.
И как следствие концепции обмена сообщениями: объекту может прилететь вызов функции, которая нереализована и в таком случае виртуальная машина Smalltalk ответит messageNotUnderstood, так как все является объектом и при этом работу с этим сообщением тоже можно переопределить, например, записав в файл какие-либо параметры, что привели к получению данного сообщения.
Такая история создания и развития языков привела к тому, что изначально было не 3-4 принципа ООП, какие известны нам сегодня, а семь. Цитирую их из книги Ю. А. Кирютенко и В. А. Савельева "Объектно-ориентированное программирование. Язык Smalltalk":
Абстрагирование - выделение объектов и их существенных характеристик, которые отличают каждый объект от всех других объектов и четко определяют возможности его использования.
Ограничение доступа - защита отдельных элементов объекта от доступа к ним извне, которая, однако, не затрагивает характеристик объекта как целого.
Модульность - свойство системы, связанное с возможностью ее представления в виде нескольких тесно связанных между собой частей (модулей).
Существование иерархий - упорядочивание по некоторым правилам процесса наследования информации объектами системы.
Инкапсуляция - концепция сокрытия в как бы «капсуле» всей информации об объекте, то есть объединение в некое целое данных и процедур (методов) их обработки.
Наследование - отношение между классами, при котором один класс (подкласс) моделирует поведение и свойства другого класса (суперкласса), добавляя свою специфику.
Полиморфизм - возможность единообразного обращения к объектам (посылки им одноименных сообщений) при сохранении их уникального поведения. Другими словами, поскольку поведение объектов определяется методами, полиморфизм означает, что методы, ассоциированные с одним и тем же именем, допускают разные реализации в разных классах.
ООП Грэди Буча
В 1980-х годах Буч подарил нам концепцию ООП в том виде, в каком видим ее сегодня. Вся концепция получила название "Метод Буча". Данный метод был описан в книге "Объектно-ориентированный анализ и проектирование" и представляет из себя набор рекомендуемых практик по разработке программного обеспечения, где как раз идет упор на создание классов и экземпляров этих классов.
Заключение и феномен смешения парадигм
Завершая заметку, хочу добавить, что во многом путаница возникает из-за пересечения функциональной и ООП парадигм языков программирования. О данном феномене отлично высказался один из разработчиков Smalltalk-76 Дон Ингаллс (на самом деле феноменом называю я сам, просто потому что так захотелось, это не официальный какой-то термин (: ) :
Язык Smalltalk является объектно-ориентированным, а не функциональным, и это часто сбивает с толку людей с предыдущим опытом работы в computer science. Например, вычислить +4 означает отправить объекту +4 как сообщение. Принципиальное отличие в том, что все контролирует объект, а не +. Если объект является целым числом 3, то результатом будет целое число 7. Однако, если бы он был строкой «Meta», результат мог бы быть «Meta4». Таким образом, смысл изменяется вместе с объектами этой системы, тогда как код остается абстрактной формой, просто направляя поток сообщений
Данный феномен отлично проявляется и в наши дни на примере мобильной разработки и развития языков Swift и Kotlin. Об этом есть отличный доклад Виталия Брагилевского:
Материалы, откуда бесстыдно наворовал информации в заметку использовавшиеся при подготовке:
- Забытая история ООП, habr
- Почему Алан Кэй не изобретал объекты, hexlet
- Полезнейший длиннопост Кирилла в твиттере, часть 1
- Полезнейший длиннопост Кирилла в твиттере, часть 2
- Ю. А. Кирютенко, В. А. Савельев Объектно-ориентированное программирование. Язык Smalltalk
- Грэди Буч, википедия
- Алан Кэй, википедия
- Про обмен сообщениями в Smalltalk, stackoverflow