Всем привет! Недавно работал над задачей. Нужно было получить из сети некоторые объекты по REST и обработать.  Ну все вроде бы ничего сложного. Загрузил, спарсил, вернул. Ок. Затем нужно было полученный массив обработать. Вкратце, по особой логике просуммировать некоторые поля - это могла быть строка, число или null. Начал делать как обычно: создал переменную sum, начал цикл for, в нем начал заниматься основной логикой. Закончил. Продолжил кодить. Хоба! Эта же логика. Не стал копипастить, вынес в отдельную функцию. Тоже все хорошо. Начал заниматься 3 задачей. Объединить результаты нескольких вычислений. Опять циклом начал перебирать. Но тут появилась мысль: “А что, если создать для этого отдельный объект?” Да нет, чушь! Ведь не существует в реальном мире ОбъединителяКакогоТоРезультата. Но что, если сделать? Попробуем. Какого!!!?? Почему все вмиг стало так просто? Передал в конструктор нужные объекты и сделал методы, которые применяли свою логику к содержащимся в них объектам. Всего-лишь несколько строчек! Почему я так раньше не делал? Я раззадорился. Начал видеть объекты везде. Это очень удобно: не нужно смотреть на каждый фрагмент кода с мыслью “а было ли это где нибудь раньше?”. А как тестировать легче стало! Тут до меня дошло, что было со мной не так:  Я не разграничивал объекты реального мира и объекты в понимании ООП. Наверное главной моей ошибкой был недостаток практики: я много интересовался, читал, смотрел, но до кодирования руки не доходили. Поэтому, к моменту того события в моей голове было только 3 паттерна использования объектов: DTO Объекты из реального мира Объекты, реализующие какой-то интерфейс (обычно для запросов по сети, для использования в DI контейнера) Оглядевшись назад понял, что все дороги вели именно к такому мышлению: В вузе нас учили ООП по каким-то моделям типа: “Вот это объект Человек. У него есть атрибуты Имя и Возраст”, а когда дело доходило до программирования, никто не смотрел как мы пишем код. Получалась каша из императивного программирования и набросков объектов. Во всяких обучающих ресурсах (видео, книги, курсы) дают слишком простые примеры. Примеры слишком прямолинейные (как в выше перечисленном вузе). Не дают почувствовать мощь объектов. Если были задачи, то слишком простые. Не тот уровень сложности, чтобы действительно над чем-то задуматься (например, приевшийся калькулятор). Они не показывали, что объекты могли бы решить многие проблемы. В программе полно таких неявных объектов - служебных объектов: считают, фильтруют, агрегируют. Никогда не задумывался над тем, что практически любой for можно (наверное, даже лучше) заменить на объект, инкапсулирующий необходимую логику. Пожалуй единственное, что меня ограничивало - идефикс, того, что объекты должны представлять концепции реального мира. Кто мне вообще это сказал? Но что насчет популярных инструментов проектирования? Нотаций. Наверное все видели различные UML диаграммы. Диаграмму классов так наверное любой программист должен был видеть хоть раз. ER диаграммы тоже хороши - они слишком сильно сцеплены с реальным миром. Там почти все представляет объекты реального мира. Поразмыслив, я понял 3 вещи: ER диаграмма ничего не имеет общего с ООП - это инструмент для бизнес-анализа. Я не обязан создавать такие же классы, как и на этой диаграмме. Кто мне такое сказал?  UML показывает высокоуровневую структуру программы: кто в ней есть и что они должны делать/иметь. Т.е. что делать, а не как делать. Реализация ложится на плечи программиста (спойлер, это будут методы на 100+ строк из циклов, условий и других прелестей) Многие нотации ориентированы для простого понимания концепций программы - из каких компонентов состоит. Ничто не мешает нам вместо классов передавать массивы object. Не нужно ориентироваться на них как на истину в первой инстанции. В итоге заканчиваем, тем что имеем много объектов. Ура, ООП! А что внутри? Громадные циклы на десятки строк, множество флагов и if’ов - полная императивщина.  Что же я понял? Например, Задача - посчитать общее время рабочих часов.Банально, да? Давайте сделаем функции: Но тут мы заметим общую начальную часть: IWorkingScheduleService service, UserSchedule schedule. Почему бы нам не вынести эту логику в отдельный объект? Как же стало удобно! Все находится рядом, сигнатуры стали короче и поддержка автодополнения в подарок - прелесть! Что я вынес из всего этого? Объект это не концепция реального мира. Можно сделать объект который имеет имя, атрибуты, поведение, как у объекта реального мира, сделать максимально похожим, но это НЕ ОБЪЕКТ РЕАЛЬНОГО МИРА. Надо прекратить думать в данном ключе! Объект - это (всего лишь) данные и функции, ассоциированные с ними  На каждый блок с логикой (цикл, последовательность условий и т.д.) я смотрю с мыслью: “Нельзя ли вынести это в отдельный объект?” Таким же образом, смотрю на функции, которые принимают одинаковые аргументы. Их всех можно объединить в объекты, атрибутами которых являются эти общие аргументы. P.S. Я не радикал, а за осмысленное и прагматичное использование объектов: для тривиальной логики можно оставить циклы, разрешаю)  Бэкэнд разработчик, но для ПМ могу быть кем угодно