Pull to refresh

Эволюция понимания ООП

Reading time 5 min
Views 15K
Почти все программисты считают, что знают ООП. Я тоже так считал. Оглядевшись немного, я понял, что эволюция моего понимания ООП была немалой. Начиналось все с простого, что есть классы, у них есть методы. И если один класс представляет какое-то понятие реального мира, то вот оно — ООП. Фактически, это не статья, а просто мысли, представление того, как менялось мое понимание ООП и отношение к нему. Кстати, я не уверен, что через пару месяцев оно вновь не претерпит некоторых изменений.

ООП прежде всего, инструмент


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

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

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

Если провести некую аналогию, то для меня это сродни кросс-платформенным средам разработки. Например, тот же .NET. Не важно, на каком языке я пишу — C#, VB или какой-то другой, я знаю, что мой код скомпилится в промежуточный. Так вот, представьте, что я, как программист использую C#, а мой заказчик говорит свои требования на VB. В такой ситуации ООП служит тем самым преобразователем, который помогает сойтись мне и заказчику, быть на одной волне (любят они фразу — to be on the same page). И вот тут открывается ключевая особенность, которая была не заметна раньше. ООП — это инструмент. Моя модель, которую я реализую у себя в коде — это инструмент. Она не обязательно будет сохраняться полностью, если мол я создал объект, поиграл с ним, изменяя его внутреннее состояние, получил от него какой-то выхлоп и теперь могу спокойно его выкинуть в мусорку. Она как отвертка, которая помогает в работе, как таблички экселя, которые я открываю, произвожу рассчеты и закрываю без сохранения. Это именно инструмент в работе с данными, а не целостная сохраняемая модель. Очень часто в командах разработчиков разделены люди, занимающиеся базами данных и люди, работающие над непосредственно кодом, моделью и пользовательским интерфейсом. Я вовсе не ратую за то, что эти команды надо разделять, я наоборот приветствую совместную работу. Так вот, если не привязываться к данным, то рефакторинг своей модели выглядит как усовершенствование нашего инструмента для работы с этим набором данных. Это все равно, что выпустить новую улучшенную дрель или новое сверло, чтобы сверлить более толстые стены.

Действие важнее того, кто его совершил


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

Задача рассчетов мыслями объектника


Не удержав себя от сравнения процедурного и объектно-ориентированного подхода, я задался простым вопросом — где бы я мог использовать процедурный подход, вместо объектного? Если честно, то я не знаю такие области, в которых ООП явно проигрывало функциональному подходу по тем или иным параметрам. Одна вещь, которая вертится на языке, все же, есть — это какие-нибудь калькуляции, сложные рассчеты, алгоритмы. Давайте возьмем пример, когда нам необходимо выполнить рассчет величины по каким-то сложным правилам. Я не знаю, как бы действовал человек, который проповедует процедурный стиль, но мысли объектника я понять могу. Пунктом первым, я бы разбил эту калькуляцию на смысловые этапы, например, подсчет вот этого коэффициента, потом этого и потом финальный. Каждый этап калькуляции — это объект, который будет участвовать во всем процессе. Для общения между шагами, чтобы дать им возможность обмениваться данными, создадим еще один вспомогательный объект, который будет хранить в себе все промежуточные рассчеты. Затем объеденим эти объекты в единую цепочку, опишем один единственный метод, который будет возвращать необходимое значение и все. Такой код будет удобно тестировать, его комфортно читать, в нем не трудно разбираться, но есть одно Но. Нужно иметь небольшой сдвиг в своем понимании, что объект — это не обязательно какое-то существительное из реального мира, это может быть еще и действие. А вот это уже становится сложнее и явно не в пользу ООП. Определить грань, где в качестве объектов используются объекты реального мира или какие-то понятия, а где объекты могут быть действиями, весьма непросто. Да и нужно приложить некое усилие, чтобы понять, как будет выглядить метод у такого объекта. Получается, поведение у какого-то действия, а это уже за гранью русского языка. Из такого моего понимания вещей я делаю вывод, что ООП действительно не самый лучший выбор для данной задачи, но лишь потому, что он может быть не всегда прост и прозрачен в понимании.
Tags:
Hubs:
+34
Comments 106
Comments Comments 106

Articles