В начале месяца в блоге StackOverflow вышел занятный пост про то, о чём спорят уже много лет, — объектно-ориентированное программирование (ООП). Мы решили перевести этот материал для читателей блога GeekBrains.
В 1981 году в августовском выпуске журнала Byte автор статьи «Object-Oriented Software Systems» Дэвид Робсон написал о новом подходе, который значительно отличался от всем известного императивного программирования:
«Многие люди, не имеющие представления о том, как работает компьютер, находят идею объектно-ориентированного программирования вполне естественной. Напротив, многие люди, имеющие опыт работы с компьютерами, сначала думают, что в объектно-ориентированных системах есть что-то странное».
Справедливо будет заметить, что создать код в виде классов и объектов, которые моделируют поведение вашей программы, — это нетривиальная задача. Разработчикам пришлось перестраиваться с процедурной парадигмы программирования на ООП и отвыкать воспринимать части кода как отдельные математические функции. Объектно-ориентированный подход обещал улучшить модульность и структурированность программ. Потом появился ещё объектно-ориентированный анализ (ООА) и объектно-ориентированный дизайн (ООД) — и стало понятно, что ООП не так просто, как могло показаться на первый взгляд. У него и сейчас немало критиков.
Одни говорят, что объектно-ориентированный код сложнее тестировать, а рефакторинг нужно производить с особой осторожностью. При повторном использовании кода возникает много сопутствующих проблем. Создатель языка Erlang так сказал об этом: вы хотите банан, но получаете гориллу, которая держит его в руках, а с ней и все джунгли в придачу. Иногда проводят такие аналогии: «процедурные» программисты похожи на поваров или химиков, которые следуют рецептам и формулам; а «объектно-ориентированные» программисты — как греческие философы или натуралисты XIX века, обеспокоенные структуризацией всего, что видят.
Был ли успех ООП случайным?
ООП остаётся доминирующей парадигмой программирования. Это связано с успехом объектно-ориентированных языков. Например, Java, C++ и Kotlin позволяют создавать мобильные приложения под Android, а Swift и Objective-C — под iOS. Вы бы не смогли разрабатывать программное обеспечение для мобильных устройств, если бы не понимали объектно-ориентированный подход. То же самое происходит и в веб-программировании (JavaScript, Python, PHP и Ruby).
Почему существует так много объектно-ориентированных языков? Здесь важно не путать причину и следствие. Конечно, можно присоединиться к мнению Ричарда Фельдмана, который утверждал, что это просто случайность. Но мы попробуем копнуть глубже и разобраться.
В начале 1980-х Бьёрн Страуструп разработал язык С++, изначально задуманный как набор расширений к С. Основываясь на С, С++ включил в себя объектно-ориентированный подход. Фельдман утверждает, что С++ стал популярным благодаря общему обновлению языка, включая безопасность типов, добавленную поддержку автоматического управления ресурсами, обработку исключений и многое другое.
Затем к С++ обратились разработчики Java. В своём языке они захотели улучшить объектно-ориентированную поддержку. В итоге компания Sun Microsystems создала ЯП с более понятным и простым в использовании объектно-ориентированным подходом.
Многие разработчики по всему миру быстро перешли на Java, этому поспособствовала тесная интеграция языка с веб-браузерами в то время. С этой точки зрения кажется, что ООП сопутствовало успеху, но не являлось основным фактором.
Что же делает ООП уникальным?
Есть три принципа, которые составляют основу ООП.
Инкапсуляция. Скрытие внутренней реализации от других компонентов — будто бы часть данных помещена в капсулу. По умолчанию в ООП данные инкапсулируются. Поскольку объекты содержат как данные, так и методы, которые могут изменять данные, то хорошей практикой считается предоставление публичных методов для получения новых значений и установки их этим данным. Так данные защищаются от нежелательных изменений и приложения становятся более безопасными.
Инкапсуляция — одно из главных преимуществ ООП. И хотя этот принцип чаще всего связывают с объектно-ориентированным программированием, само понятие фактически отделено от него и может быть реализовано без использования объектов и классов. Рука об руку с инкапсуляцией идёт абстракция. Там, где инкапсуляция скрывает внутреннюю информацию, абстракция обеспечивает более простой в использовании открытый интерфейс для данных. В любом случае инкапсуляция и абстракция относятся не только к ООП — их можно реализовать с помощью модулей данных, а также операций над ними в пределах модуля.
Наследование. Этот принцип ООП позволяет создавать производные классы (классы-наследники), взяв за основу все методы и поля базового класса (родителя). При этом производным классам не нужно определять повторно члены базового. Это соответствует одному из главных паттернов программирования (DRY) и позволяет повторно использовать компоненты программного обеспечения. В функциональном программировании принцип DRY можно выполнять, повторно используя функции. Так же обеспечивается и эффективность использования памяти.
Хотя наследование — это очень мощная возможность в ООП, многие программисты используют вместо него композицию — из-за большей гибкости во взаимодействии между объектами различных типов. Если полностью отказаться от наследования, то классы и методы быстро потеряют роль синтаксического сахара для структур и процедур. Наследование крайне важно для полиморфизма, о котором поговорим дальше.
Полиморфизм. Этот принцип означает, что объекты с одинаковой спецификацией могут иметь разную реализацию. Полиморфизм позволяет писать более абстрактные программы и повышать коэффициент повторного использования кода. Выделяют два вида полиморфизма:
- параметрический полиморфизм, когда обрабатываются значения разных типов идентичным образом;
- ad-hoc-полиморфизм, предоставляющий единый интерфейс к потенциально различному коду для допустимых в данном контексте типов.
Объектно-ориентированное программирование сложно представить без полиморфизма, однако это понятие не ограничивается ООП.
Оценив эти преимущества, можно прийти к выводу, что в 2020 году концепция ООП уже не так уникальна по сравнению с другими парадигмами влияния. Опытные программисты будут упрощать код, используя комбинацию из нескольких парадигм. Если посмотреть на теги, которыми отмечаются обсуждения ООП и функционального программирования, чаще всего там можно увидеть JavaScript.
Что будет дальше?
ООП добилось успеха — возможно, вследствие того, что огромные индустрии опираются на эту парадигму и в свою очередь поддерживают её.
А что насчёт самих разработчиков? Опрос 2020 года показывает, что они всё больше зависят от того, во что вкладываются работодатели. Сейчас Haskell и Scala — одни из любимых языков программирования. Scala приносит самые высокие зарплаты. Возможно, с популяризацией функционального программирования эти языки закрепят лидерство в рейтинге.
Здесь уже есть подвижки. Крупные компании, в том числе Twitter, почти полностью пишут бэкенд на Scala, а Facebook недавно использовал Haskell. Многие из основных языков ООП также принимают функциональные возможности. В .NET есть LINQ, а в Java 8 — Lambdas. JavaScript становится всё более функциональным. Swift — золотая середина между объектно-ориентированным и функциональным языком. Так что, возможно, не надо выбирать: у вас может быть свой класс Cake и функция EatCake().
Сентябрь — отличное время, чтобы построить далеко идущие планы и начать идти к новым целям! Если вы хотите освоить профессию мечты, то с 22 по 31 сентября 2020 г. мы дарим вам скидку 40% почти на все программы обучения GeekBrains. Успехов! :)