Рассказываю об одной из важнейших парадигм в программировании.
Парадигмы программирования и их виды
Парадигма разработки – это набор правил и критериев, соблюдаемых разработчиками, чтобы выдержать конкретную стилистику и модель написания кода.
Единая парадигма помогает избегать ошибок, упрощает работу в команде и ускоряет разработку. Ориентируясь на одну парадигму, можно корректно структурировать код приложения, зная четкие правила, выбранные командой, которая работает над конкретным проектом.
Существуют различные типы парадигм, например процедурный, ориентированный на работу с функциями, или логический, подразумевающий решение базовых логических задач в духе «если А = true, то и B = true». Но есть и более интересный подход к решению задач разработки, и это ООП-парадигма.
Что такое ООП?
Объектно-ориентированное программирование, ООП – это одна из парадигм разработки, подразумевающая организацию программного кода, ориентируясь на данные и объекты, а не на функции и логические структуры.
Обычно объекты в подобном коде представляют собой полноценные блоки с данными, которые имеют определенный набор характеристик и возможностей. Объект может олицетворять что угодно – от человека с именем, фамилией, номером телефона, паролем и другой информацией до мелкой утилиты с минимумом характеристик из реального мира, но увеличенным набором функций. Объекты могут взаимодействовать друг с другом, пользователем и любыми другими компонентами программы.
ООП заставляет разработчиков фокусироваться на объектах, которыми нужно манипулировать, а не на той логике, что позволяет изменять данные и как-то с ними взаимодействовать. Такой подход хорошо работает в случае с комплексными программными решениями, требующими постоянной поддержки со стороны большого числа программистов.
Структура объектно-ориентированного программирования
Программный код, написанный с учетом принципов ООП, четко структурируется на 4 основных элементах (иногда выделяют и больше, включая в список элементов модули и другие структуры, связанные с объектно-ориентированной парадигмой, но мы обратимся к ним позже, говоря о преимущества и принципах описываемой модели).
Объекты
И хотя в структуре ООП объекты находятся не на первом месте, мы начнем с них, так как это упрощает общее понимание парадигмы.
Объект – это кусок кода, описывающий элемент с конкретным набором характеристик и функций. Например, вы делаете видеоигру, в которой есть персонаж. Ваш герой.
Этот персонаж в коде может быть отдельным объектом с такими характеристиками, как здоровье, сила, выносливость, ловкость и урон, а также функциями (методами) – это могут быть магические способности или особые приемы, используемые персонажем.
Объекты могут описывать других персонажей и средства передвижения.
Методы
Методы – это функции, описанные внутри объекта или класса. Они относятся к конкретному объекту и позволяют взаимодействовать с ними или другими частями кода. Выше мы уже затронули «способности» персонажа-объекта, вот они и являются наиболее понятным описанием методов. Когда ваш персонаж выполняет действие в игре, он задействует метод, описанный в его объекте.
Атрибуты
Атрибуты – это конкретные характеристики объекта. Если вы хоть немного знакомы с программированием, то атрибуты можно представить в виде переменных с данными. Вернувшись к примеру с игровым персонажем, в качестве атрибутов можно представить характеристики в духе уровня выносливости, скорости и других статических показателей.
Классы
Это наиболее абстрактная и обобщенная форма в ООП. Что-то в духе шаблона, на базе которого строятся другие элементы структуры кода.
Снова поясню на примере игры. В какой-нибудь онлайн-РПГ может быть куча разных героев: воины, лучники, люди, орки. Описывать каждого по отдельности сложно и нецелесообразно, ведь у них много общих характеристик и методов.
Поэтому мы можем создать класс – то есть объект, способный стать базой для других объектов. Например, класс – персонаж. Он умеет ходить, драться, имеет характеристики наподобие уровня здоровья или количества маны, то есть атрибуты, что есть у любых рас и классов в нашей РПГ. А уже человек-воин (объект) с ником Nagibator777 будет содержать более специфичные характеристики и методы, зависящие от решений игрока и других внешних факторов. Класс – это пример абстракции и наследования, упрощающий генерацию новых объектов.
На картинках и схемах эта структура выглядит куда понятнее.
Ключевые принципы ООП
Объектно-ориентированное программирование исповедует ряд принципов, лежащих в основе правил создания и использования всех структурных элементов, включая классы, объекты, методы и прочие компоненты.
Инкапсуляция
Этот принцип гласит, что вся важная информация, необходимая для работы объекта, в нем же и хранится. И только определенные данные доступны для внешних функций и объектов.
Данные конкретного объекта или класса хранятся в пределах этого объекта или класса. Вносить в них изменения, используя другие классы, нельзя. У окружения есть право только запрашивать «публичные» методы и атрибуты.
Такой подход обеспечивает повышенный уровень безопасности, а также сокращает шансы на случайное повреждение данных внутри какого-то класса или объекта со стороны.
Наследование
Это как раз основная суть взаимоотношений между классами и объектами, описанная выше. Чтобы не создавать кучу одинаковых объектов или классов, можно создать класс над классами с более общими характеристики и функциями, а потом постепенно наследовать от него те или иные возможности. Используя специальную конструкцию, программист может забрать из класса ряд атрибутов или методов, оставить их в прежнем виде и дополнить новыми или же слегка переосмыслить на свое усмотрение, а потом создать из них уникальный объект или подкласс для дальнейшего наследования опций.
Это проще понять на примере со средствами передвижения:
Берем абстрактный класс «Средство передвижения» с возможностью набирать скорость и перевозить людей.
Из него формируем подкласс «Автобус», наследующий базовые характеристики и уточняющий их определенным количеством мест для людей и пределом скорости.
Затем создаем объект «Икарус» с более конкретной скоростью, планировкой, количеством дверей, типом сигнала и другими специфичными параметрами.
Не нужно каждый раз создавать новый класс или объект с полным набором опций. Достаточно воспользоваться конструкцией в духе export class Bus extends Vehicle()
и дополнить код конкретикой.
Абстракция
Каждый верхний слой над объектом (классы) более абстрактный, чем его «младшая версия». Это позволяет не переписывать по 10 раз один и тот же объект, указывая одни и те же атрибуты и методы. Напротив, абстрактные классы позволяют создавать все более конкретные классы и вытекающие из них объекты, не описывая реализацию функций заранее (в этом и суть абстракции), а оставляя исключительно базовый шаблон для дальнейших надстроек.
Абстрактный класс должен оставаться публичным и не содержать реализации методов. Этим он отличается от дочерних классов.
Полиморфизм
Один из ключевых принципов ООП, позволяющий использовать одни и те же методы для обработки различных типов данных. Полиморфизм в разных языках программирования отличается: есть строго типизированные языки в духе C++, где задействуется «перегрузка», а есть такие языки, как JavaScript, где по умолчанию функции могут обрабатывать разные типы информации без необходимости указывать тип заранее.
Полиморфизм позволяет с помощью идентичных методов обрабатывать разные типы данных, например двузначные числа и числа с плавающей точкой. Также полиморфизмом считается возможность переопределять методы в дочерних классах для обработки других видов данных или выполнения дополнительных действий при вызове аналогичного метода.
Преимущества ООП
Основными преимуществами парадигмы разработчики считают следующие особенности:
Модульность: инкапсуляция объектов в себе упрощает разработку, уменьшает количество ошибок и ускоряет разработку при участии большого количества программистов, так как каждый может работать независимо друг от друга.
Реюзабельность кода: благодаря абстракциям, полиморфизму и наследованиям можно не писать один и тот же код много раз, что заметно ускоряет создание нового ПО.
Высокая скорость разработки: классы и интерфейсы в ООП могут легко трансформироваться в подобие полноценных библиотек, которые можно переиспользовать в новых проектах.
Расширяемость: ООП-код легче развивать, дополнять и менять. Этому способствует независимая модульная структура.
Простота восприятия: использование ООП упрощает понимание кода за счет взаимодействия с объектами, а не логикой. Не нужно углубляться в то, как построено ПО, чтобы модифицировать его.
Безопасность: инкапсулированный код недоступен извне, поэтому «поломать» ООП-программу сложнее.
Гибкость: полиморфизм позволяет быстро адаптировать ООП-код под свои нужды, не описывая новые функции и объекты.
Недостатки ООП
Разработчики ругают объектно-ориентированную парадигму за то, что та ставит во главе угла объекты и не уделяет достаточно внимания вычислениям и алгоритмам. По мнению некоторых программистов, такой подход местами заставляет писать больше кода, чем понадобилось бы при использовании функциональной парадигмы. Также ООП-код негативно сказывается на скорости компиляции кода.
Языки, исповедующие объектно-ориентированную парадигму
Существует множество языков программирования, подходящих для применения ООП-парадигмы. Среди них:
Ruby – высокоуровневый язык с динамической типизацией, созданный в середине 90-х японским разработчиком Юкихиро Мацумото.
С++ – статически типизированный язык программирования общего назначения, в первую очередь направленный на работу с ООП.
JavaScript – популярный язык с динамической типизацией, одинаково хорошо подходящий для различных парадигм разработки, включая ООП.
Также в число языков с акцентом на ООП-парадигме входят: C#, Python, Java, PHP, JADE, Scala и другие.
Вместо заключения
Объектно-ориентированное программирование – популярная практика среди разработчиков, позволяющая делать сложные приложения и часто использующаяся в крупных корпорациях. Это интересная модель, с которой стоит ознакомиться всем, кто хочет делать логические модульные структуры и сокращать количество потенциальных ошибок и проблем с безопасностью в своих программах.