Вас неправильно учили объектно-ориентированному программированию

ООП — это парадигма, которая предоставляет ряд возможностей для создания наиболее эффективного программного обеспечения из наиболее элегантного и оптимизированного кода. Однако, чтобы извлечь выгоду из этих возможностей, необходимо понять, что такое объектная ориентированность.

Во многих учебных заведениях преподают ООП, оторванное от реальности. Таким образом, ключевые части этой модели программирования остаются без внимания. В результате много времени тратится на обучение примерам, которые не имеют практического применения и не помогают решать реальные.

Эта статья посвящена выявлению причин и последствий неверного представления многих людей об ООП. Мы также поговорим о реальном преимуществе объектной ориентированности, которое часто упускается из виду на университетских занятиях.

Класс-ориентированное или объектно-ориентированное?

Одна из главных проблем заключается в том, что большинство людей изучают ОПП как класс-ориентированное, а не объектно-ориентированное программирование.

Помню (это было как будто вчера) мучения, которые мне пришлось испытать в колледже. В течение целого семестра я пытался совладать с абстрактными диаграммами и примерами иерархий животных, которые не имели никакого смысла. В то время как основное внимание уделялось моделированию классов, взаимодействие между объектами — основа ОПП — игнорировались.

Это была настоящая пытка и даже хуже — потраченное впустую время. Ведь суть объектного подхода заключается в возможности материализовывать сложные идеи, алгоритмы и абстракции в простом и элегантном коде.

Как я понял, преподавание ООП часто фокусируется не на процессе, а на структуре данных. В результате человек получает представление о статических объектах, не понимая, как взаимодействовать с объектами во время выполнения программы. Эта линейная и последовательная структура отражает скорее процедурное программирование, которое работает пошагово, чем возможность символического представления, которым отличается ООП.

Как я уже упоминал, в ООП недостаточно знать, как создавать классы, определять методы, публичные или частные режимы доступа к атрибутам. Вам нужно хорошо организовать отношения между объектами. Для этого необходимо использовать силу абстракции, которая позволит сосредоточиться на результате написания кода, а не зацикливаться только на задачах.

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

Недооцененное достоинство

ООП позволяет создавать программное обеспечение с возможностью постоянного его совершенствования, не требуя при этом перестройки всей системы. При изменении процесса вам не нужно заново пересматривать весь код и всех переучивать. В этом разница между процедурным подходом и объектно-ориентированным.

ООП предоставляет идеальный интерфейс, позволяющий осуществлять сотрудничество без регулирования действий других. Это именно то, что присуще хорошей команде. Хорошая команда, работая сообща, фокусируется не на задаче, а на результате. Это парадигма доверия, а не контроля.

Реальный пример разницы между двумя парадигмами

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

Это яркий пример процедурного подхода: банк выделил ресурсы для контроля всего процесса, аккумулируя 2 обязанности: обслуживание посетителей и управление очередью.

Вместо того, чтобы сосредоточиться на повышении качества обслуживания, он направил энергию не на основную, а на побочную деятельность. Неоправданная растрата ресурсов, безусловно, увеличила время обработки очереди клиентов.

С подобной ситуацией вы сталкиваетесь в своем коде всякий раз, когда имеете дело с циклом “for” или “while”, отвечающим за выбор следующего элемента, связанным с обработкой самого элемента. Это классическая связка.

Парадигма эффективности

А вот другой пример. На днях мне пришлось отвезти своего друга на вакцинацию. Медицинский центр, в отличие от банка, реализовал иную стратегию. Медсестры полностью сосредоточились на мобилизации своих немногочисленных ресурсов, направив их на обеспечение наилучшего обслуживания населения.

Не имея возможности организовать очередь, они делегировали эту ответственность другой части системы — посетителям.

Когда я приехал со своим другом, то заметил людей, ожидающих перед дверью, и спросил: “Кто последний в очереди?”. Мне указали на человека, он подтвердил это, я представился новым последним в очереди и начал ждать. Вскоре появился еще один человек, который, как и я, занял очередь, приняв установленные правила.

Затем дверь открылась, и медсестра крикнула: “Следующий!”. Первый в очереди встал и направился в кабинет. Далее каждый раз, когда открывалась дверь, медсестра просто выкрикивала волшебное слово “следующий”.

Это демонстрирует полное разделение обязанностей между организацией очереди и самим обслуживанием. Для медсестер пациенты были инкапсулированы в объект итератора, который всякий раз при получении сообщения “закрыть” предоставлял только следующего пациента, независимо от того, кем он являлся и как был организован в очереди.

В этом итераторе все пациенты были организованы в двусвязный список, где каждый знал только своего предшественника и преемника, не беспокоясь о порядке всего списка.

Такое разделение обязанностей позволяет даже изменять очередь, никак не влияя на работу медсестер. Ведь все, что для них имеет значение, — знать, кто следующий. Так и вам при выполнении ООП не нужно знать имя, индекс или внутреннюю структуру данных, используемые для общей организации, — имеет значение только следующий элемент.

В ваших силах перенести акцент с контроля на доверие с помощью более четких интерфейсов, позволяющих объектам сотрудничать в решении проблемы.

Объектная ориентированность: далеко за пределами поверхностного подхода

Чтобы визуализировать и реализовать эффективную стратегию, вы должны сосредоточиться на том, как будет происходить обработка, а не на чрезмерной привязке к выявленным и очевидным объектам (классам, методам, атрибутам и т.д.). В конечном счете, самое важное — это не сами объекты, а взаимодействие между ними.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод Josef Cruz: What People Learned About Object-Oriented Programming Is Wrong

Предыдущая статьяReact Single Page Application и React-Router для начинающих
Следующая статья6 отборных практик для определения метода __init__ в Python