(Объектно-Ориентированное Помешательство)

Описание:
Заразное ментальное расстройство, поражающее программистов, чрезмерно увлекающихся объектно-ориентированным программированием (ООП) и паттернами проектирования. Симптомы включают неспособность писать простой код, чрезмерное усложнение архитектуры и патологическую потребность во внедрении фабрик, стратегий и синглтонов даже там, где они не нужны.

Симптомы:

1. Клиническая полиморфофилия

  • Больной не может написать простой метод, не завернув его в десяток интерфейсов и абстракций.

  • Любая функция превращается в класс с тремя уровнями наследования.

Пример:

Вместо `print("Hello, World!")` больной пишет:

class Message:
    def get_text(self):
        pass

class HelloWorldMessage(Message):
    def get_text(self):
        return "Hello, World!"

class MessagePrinter:
    def print(self, message: Message):
        print(message.get_text())

printer = MessagePrinter()
printer.print(HelloWorldMessage())

“Зато гибкость!” – уверяет больной.

2. Синдром “Фабрики фабричных фабрик”

  • Каждая новая сущность создаётся исключительно через фабричные методы или фабрики.

  • Больной испытывает тревогу, если объект создаётся без фабрики.

Пример:

class Car:
    pass

class CarFactory:
    def create_car(self):
        return Car()

class CarFactoryFactory:
    def create_factory(self):
        return CarFactory()

factory = CarFactoryFactory().create_factory()
car = factory.create_car()

Больной гордится “гибкостью” системы, хотя коллеги в шоке.

3. “Наследовать – значит существовать”

  • Пациент не может создать сущность без наследования.

  • Даже простые структуры данных превращаются в сложные иерархии.

Пример:

class Animal:
    def make_sound(self):
        pass

class Mammal(Animal):
    pass

class Primate(Mammal):
    pass

class Human(Primate):
    def make_sound(self):
        print("Hello, World!")

person = Human()
person.make_sound()

На вопрос “Зачем столько уровней?” больной отвечает: “На будущее, для расширяемости!”

4. Обсессивное применение паттернов проектирования

  • Пациент не может писать код без применения какого-либо паттерна.

  • Даже самые простые задачи решает через стратегию, декоратор или мост.

  • Отрицает существование кода, написанного без паттернов.

Пример:

Вместо простого условия:

if user.role == "admin":
    grant_access()

Больной пишет:

class RoleStrategy:
    def grant_access(self):
        pass

class AdminRole(RoleStrategy):
    def grant_access(self):
        grant_access()

strategy = AdminRole()
strategy.grant_access()

“Так ведь SOLID!” – гордо заявляет больной.

5. Полное отрицание процедурного и функционального программирования

  • Больной считает, что процедурный код – это признак непрофессионализма.

  • Лямбды, функции и даже простые скрипты вызывают у него физическое отвращение.

  • Каждая функция превращается в метод класса, даже если ей это не нужно.

Пример:

def add(a, b):
    return a + b

Пациент переписывает на:

from abc import ABC, abstractmethod

# Абстрактный класс для чисел
class Number(ABC):
    @abstractmethod
    def get_value(self):
        pass

# Конкретная реализация чисел
class Integer(Number):
    def __init__(self, value: int):
        self.value = value

    def get_value(self):
        return self.value

# Абстрактный класс калькулятора
class Calculator(ABC):
    @abstractmethod
    def add(self, a: Number, b: Number) -> Number:
        pass

# Конкретная реализация калькулятора
class BasicCalculator(Calculator):
    def add(self, a: Number, b: Number) -> Number:
        return Integer(a.get_value() + b.get_value())

# Использование
num1 = Integer(5)
num2 = Integer(10)
calculator = BasicCalculator()

result = calculator.add(num1, num2)
print(result.get_value())  # Выведет: 15

“Объектно-ориентированный подход!” – уверяет больной.

Методы лечения:

1. Шоковая терапия: заставить пациента написать проект на чистом C или Go.

2. Функциональное программирование: вводить в рацион элементы Haskell и Elixir.

3. Чтение кода Кена Томпсона и Роберта Мартина: помогает осознать, что хороший код – это не про количество классов.

4. Детокс: временный запрет на DI-контейнеры и фабрики.

5. Терапия процедурными скриптами: написать полезный скрипт в 10 строк, осознать, что это работает, и заплакать.

Прогноз:

  • В лёгких случаях пациенты могут вернуться к нормальному программированию.

  • В тяжёлых случаях остаются архитекторами на Java и требуют рефакторинга даже у домашнего ToDo-списка.

Заключение

«ООП головного мозга» – опасное расстройство, приводящее к избыточной сложности кода. Если ваш коллега пишет адаптер для вывода “Hello, World!”, немедленно вызывайте специалиста!

P.S.: Текст полностью написан ChatGPT, но он настолько хорош, что не мог не поделиться ))

Комментарии (259)


  1. kalbas
    30.01.2025 07:33

    Если не брать то, что примеры немного утрированы, и некоторые упомянутые вещи (например SOLID это далеко не всегда про ООП, скорей про общую организацию кода), в целом статья великолепна. Я недавно сменил место работы и тут DI завезен по полной и все перекрыто иерархиями в микросервисе из одной ручки, нахожусь в перманентном удивлении и пока еще так и не понял, что происходит.


    1. PlatinumKiller
      30.01.2025 07:33

      Это называется: Архитектора на кол и как чучело на масленицу сжечь…

      По факту DI если и нужен то меня вот уже давно мучает вопрос, зачем строить фабрики из всего чего можно чтобы в DI мы могли засунуть сущность, когда просто на протоколах/интерфейсах все делается и так. Зачем мне контейнер, а многие не понимают что все выше описанное в 99% случаях не копию объекта в фабрике отдаст, а сам объект, а потом стди ломай моз где этот кадр сломал все..


      1. rbdr
        30.01.2025 07:33

        Архитектор далеко и находится в сильно защищеном цод openai (среди сонма других виртуальных гениев). Хехе.


      1. jimquery
        30.01.2025 07:33

        Могу похвастаться - я за свою жизнь осознанно написал всего одну фабрику - по типу viewset's в Django DRF. Она инстанцирует кучу однотипных вьюшек во внутреннем проекте.


    1. RH215
      30.01.2025 07:33

      например SOLID это далеко не всегда про ООП

      Я вообще за то, чтобы сократить SOLID до фразы "делайте нормальные интерфейсы, б***!".


      1. feelamee
        30.01.2025 07:33

        лучше до - будьте последовательны, б***!

        совет вообще на всю жизнь)


        1. Politura
          30.01.2025 07:33

          Давно уже есть идеальный вариант:

          Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.


        1. Thetafelius
          30.01.2025 07:33

          Здравствуйте, нужное делойте, а ненужное не делойте, досвидания.


          1. IgorDev
            30.01.2025 07:33

            правильоне деплойте, а неправильное не деплойте


    1. gexeg
      30.01.2025 07:33

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

      Например у нас: есть стандартый шаблон, разворачивающийся за секунду. В нем стандартная иерархия: презентация, прикладной, доменный и инфра. То, что в 2-3 сервисах из 100, задача на столько проста, что можно не заморачиваться насчет моделек, еще не говорит что нужно городить огород и делать в этих сервисах по разному. Нужно задавать вопрос "на сколько это проблемно завести прикладной сервис, дернуть его из слоя перезентации и отдать данные?".

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


      1. ednersky
        30.01.2025 07:33

        В принципе микросервис из одной ручки уже звучит странно.

        погуглите "амазон-лямбда" или "яндекс-лямбда".

        звучит странно, но хорошо работает. Смысл в том, что сервер у провайдера может выполнять/держать на готове множество разнообразных таких микросервисов. Если к ним нет обращений, то они как бы и не запущены, а если обращений много, то и серверов, их держащих, тоже станет много. Автоскейлинг, все дела.

        ну и представьте себе микросервис над базой данных пользователей, например.

        каждый пользователь может зайти, исправить свой профиль (аватарку, там, добавить или ещё чего) и таких запросов условно N. Ну и каждый пользователь на каждый рефреш странички выполняет авторизационные/аутентификационные запросы и таких запросов условно 10000N.

        так вот с точки зрения логики удерживать весь функционал пользователя в одном микросервисе хорошо, удобно, и так далее.

        а с точки зрения нагрузки логично выделить авторизацию/аутентификацию в отдельный микросервис. Который вполне вероятно будет микросервисом из одной ручки (если ручки метрик и логгирования не считать)


        1. gexeg
          30.01.2025 07:33

          С Func as service я знаком. Не знаю имел ли в виду автор именно их.

          Не, с точки зрения нагрузки не логично или не факт что логично следовать шаблону "сервис имени ручки". Тут нужно смотреть на конретику, а то может совместить несколько сценариев (ручек) в одном даже выгоднее будет (общая бд, кэширование, отсутствие походов по сети, отсутствие репликации и т.д.).


  1. dv0ich
    30.01.2025 07:33

    Слепое фанатичное следование чему угодно - даже самой Лучшей, Доброй и Гениальной концепции - порождает только проблемы, дичь, трэш и угар.

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

    У каждой медали есть обратная сторона и это надо бы учитывать.


    1. soul-catcher
      30.01.2025 07:33

      Какой-либо паттерн предназначен для решения определённой проблемы. Решаемая проблема является частью самого паттерна. Без неё он не может существовать.

      В примерах кода я не увидел ни одного применения паттерна.

      А так это выглядит как мартышка и очки. "Очки не всегда полезны, потому что их применимость ограничена и многие их зря фанатично применяют".

      То есть, треш и угар порождается не при слепом следовании какой-либо лучшей, доброй и гениальной концепции, а при следовании искажённому представлению о концепции в голове. Обратная сторона или же применимость является частью концепции, а не находится где-то снаружи.

      UPD: поэтому мой голос за то, что автор не понимает ООП и не знает паттернов проектирования.


      1. PlatinumKiller
        30.01.2025 07:33

        А ничего что паттерны это лишь советы а не план для действия?


        1. RH215
          30.01.2025 07:33

          Ни то, ни то. "Паттерны" - это набор именований для часто используемых решений в SE. Значительная часть святого пула паттернов изобретается самостоятельно при первом столкновении с определённой проблемой.


          1. pawnhearts
            30.01.2025 07:33

            Вот, кстати, да. Либо потому что сталкивался с ним в библиотеках или другом коде, который изучал. И когда появляется похожая проблема решение обычно очевидно, это вообще как-то интуитивно всё. А вот если специально их "изучать" на каких-то обычно очень искуственных примерах, потом пытаться применять везде где не надо получается фигня.


      1. dv0ich
        30.01.2025 07:33

        То есть, треш и угар порождается не при слепом следовании какой-либо лучшей, доброй и гениальной концепции, а при следовании искажённому представлению о концепции в голове.

        Как отличить одно от другого? Если человек имеет искажённое представление о концепции, из-за чего не видит границ её применимости или намеренно игнорирует их - то это и выглядит как фанатизм и слепое следование.

        В результате человек начинает, например, воевать против синглтонов как таковых. Или против исключений как таковых.


    1. stanislavskijvlad
      30.01.2025 07:33

      После ваших слов захотелось пересмотреть фильм "Догма".


    1. Javian
      30.01.2025 07:33

      Любая концепция, доведенная до абсурда, является совершенством с точки зрения этой концепции.


  1. a-tk
    30.01.2025 07:33

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


    1. ionicman
      30.01.2025 07:33

      Проблемы 3:

      1. Это не управление сложностью, а перекладывание ее по разным ящикам, ибо сложность - это всегда константа, это понимаешь с опытом - т.е. что-то дает возможность просто сделать одно, в тоже время дает сложность сделать что-то другое - утрированный пример - сделал все по всем лучшим принципам - хорошо расширяется, тестируется, мокится - но вместо 1 файла получил 15 с хитрой связкой компонент и вложенности их друг в друга, и новый дев вникает в это месяц, а сам ты, вернувшись в свой код через год - два :)

      2. Попытка использовать везде одни и теже инструменты и подходы. Типа: "ООП и СОЛИД хорошо - везде про это написано, давайте и тут запилим" - а там одна функция из 10 строк во временном скрипте, который один раз в жизни должен выполнится для получения временых данных, которые будут использованы один раз - зато круто и расширяемо и по бест практис :)

      3. Большинcтво компонентов софта не живет больше 1-2 лет, за исключением энтерпрайза и некоторых других исключений, не надо думать и закладывать туда все возможное и делать максимально универсально, нужно всегда делать балансируя между достаточной универсальностью и простотой - и именно это и есть золотая грань, которую да - очень сложно держать. Не надо бояться переписывать и рефакторить - иногда проще и быстрее переписать компонент с нуля на современном фрейморке и в современной парадигме, учтя опыт его текущего использования и контекста, чем пытаться патчить/расширять существующий.

      Ну и, всегда стоит помнить статью "Вы - не Гугл" :)


      1. tolyanski
        30.01.2025 07:33

        Большинcтво компонентов софта не живет больше 1-2 лет

        эт конечно вы загнули) БОЛЬШИНСТВО компонентов живет 5-10-15 лет, к сожалению...

        Не надо бояться переписывать

        пока по башке не получили от продакта или собственника бизнеса


        1. Wendor
          30.01.2025 07:33

          Про 1-2 года.... я даже услышал как WordPad/notepad/calc икнули)


          1. questpc
            30.01.2025 07:33

            Огромное количество кода живет и поддерживается более 10 лет. И паттерны как раз в этом случае очень полезны. Если кода много и это не однодневка.

            Вообще борьба с паттернами связана с ростом популярности Javascript, в котором нет нормальных полноценных классов с множественным наследованием, нет полноценных метаклассов.


          1. HabrArkady
            30.01.2025 07:33

            В этот же перечень можно добавить COBOL, Fortran, которым далеко за 60, и которые до сих пор являются основополагающими во многих областях. COBOL никак не могут заменить в банковской сфере, а на FORTRAN-е написано огромное количество научных программ, переписать которые тоже проблематично. И вот эти пенсионеры не используют ни классы, ни паттерны, ни SOLID и никакие другие аналогичные вещи. И разобраться в коде COBOL-а, Fortran-а ой как проблематично. То, что выдается за хороший код и называется хорошим, это больше вопрос привычки. Если человек привык работать с определенными операторами и они у него хорошо отложились в голове, то для него и код хороший. И попробуйте в этот код добавить, всеволишь, несколько незнакомых операторов. Крику, возгласов, эмоций будет выше нормы, мягко говоря. И, пожалуйста, не надо привычку - работать с определенными операторами и по определенным правилам - выдавать за хороший код. Все эти новомодные тенденции, такие как классы, паттерны и прочее, так сильно нагружают систему, что говорить о качестве кода не приходиться. Хороший код не может быть простым.


            1. IUIUIUIUIUIUIUI
              30.01.2025 07:33

              И вот эти пенсионеры не используют ни классы, ни паттерны, ни SOLID и никакие другие аналогичные вещи. И разобраться в коде COBOL-а, Fortran-а ой как проблематично.

              Может, тут есть какая-то связь?

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

              Да не, ерунда какая-то.


              1. SpiderEkb
                30.01.2025 07:33

                Может, тут есть какая-то связь?

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

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

                Так что вопрос знаний, пониманий и привычки на самом деле.


            1. a-tk
              30.01.2025 07:33

              Скорее так: слишком простой код вряд ли будет полезным.


        1. a-tk
          30.01.2025 07:33

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


        1. PlatinumKiller
          30.01.2025 07:33

          Ну 5 лет нигде не видел, видел больше пока работает старый принцип: «Работает - не трогай»

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


          1. SpiderEkb
            30.01.2025 07:33

            Ну 5 лет нигде не видел, видел больше пока работает старый принцип: «Работает - не трогай»

            Естественно. Потому что любое изменение кода тащит за собой регресс-тесты. И бом больше система, тем больше объем этих тестов. В результате вы тратите час на минорные изменения небольшого участка кода, а потом две недели уходит на ретест (компоненты-бизнес-нагрузка-интеграция-прелайв...) потому что этот модуль mission critical и используется из 100500 других mission critical модулей...


        1. SadOcean
          30.01.2025 07:33

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


      1. avshkol
        30.01.2025 07:33

        Как раз раскладываение кода по разным ящикам - один из способов управления сложностью.


        1. a-tk
          30.01.2025 07:33

          Особенно если на ящиках нормально написано, что в них лежит.


      1. pes_loxmaty
        30.01.2025 07:33

        Это не управление сложностью, а перекладывание ее по разным ящикам

        Так ведь divide et impera

        Вам вероятно не попадались проекты такого размера, что он не может уместиться целиком в голове одного человека (ну во всяком случае новичек в команде не сможет преисполниться за вменяемое время)


      1. Nipheris
        30.01.2025 07:33

        Большинcтво компонентов софта не живет больше 1-2 лет, за исключением энтерпрайза и некоторых других исключений, не надо думать и закладывать туда все возможное и делать максимально универсально.

        Тут что-то на фронтэндерском, не получается прочитать.


        1. PlatinumKiller
          30.01.2025 07:33

          Поверь на фронте так же, максимум формочку перересуем, а что внутри только при атомной войне


      1. mitix
        30.01.2025 07:33

        Про "сложность - это всегда константа", честно говоря не понял, что это значит?


        1. PlatinumKiller
          30.01.2025 07:33

          Значит что как не дроби проект сложность всегда одна, но при дроблении его части становятся меньше, вопрос взамодействия лишь.


          1. mitix
            30.01.2025 07:33

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


            1. SpiderEkb
              30.01.2025 07:33

              Ну в том и заключается процесс - разбить большую нереализуемую задачу на много мелких реализуемых :-)


              1. a-tk
                30.01.2025 07:33

                ... а потом не запутаться в их композировании обратно


                1. SpiderEkb
                  30.01.2025 07:33

                  А вот это уже вопрос правильного разбиения и минимизации количества зависимостей. И это уже не зависит от того, ООП там или не ООП.


                  1. mitix
                    30.01.2025 07:33

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


                  1. a-tk
                    30.01.2025 07:33

                    Минимизироваться должна связка {количество компонентов, сложность каждого компонента, количество связей конкретного компонента, общее количество связей, длина пути между функционально связанными компонентами, наверняка что-то ещё}.

                    Архитектуру можно считать относительно успешной, если интегральный рост этих метрик медленнее, чем функциональность проекта.

                    Дальше может быть дискуссия как это всё считать, но я бы не хотел открывать этот ящик Пандоры.


                    1. SpiderEkb
                      30.01.2025 07:33

                      Ну мы работаем в модели, близкой к модели акторов. Т.е. логическая функция - это отдельный бинарник.

                      Стек позволяет - тут процедура (функция) на уровне языка может быть где угодно - в том же коде, в сервисной программе (аналог динамической библиотеки) или в виде отдельной программы. Нужно просто правильно указать в прототипе - extproc для сервисной программы (с подключением нужной binding directory - аналог библиотеки импорта) или extpgm с указанием имени программы если это отдельная программа.

                      Это позволяет

                      1. Локализовать всю логику и внутренние данные внутри отдельного бинарника, оставив снаружи только интерфейс с входными и выходными параметрами (контракт)

                      2. На этапе тестирования делать мок для потребителей, тестировать логику модуля без привязки к потребителю

                      3. При необходимости изменения логики (или оптимизации) делать это только в рамках одного модуля, не затрагивая (совсем) потребителей (при условии сохранения контракта), которых могут быть десятки или сотни.

                      4. Работать с компактными модулями, не более 1000 строк в среднем (бывают и больше, но не часто).

                      Но это, опять, не про ООП, а про общую архитектуру.


            1. gexeg
              30.01.2025 07:33

              Не только субъективную, но и объективную в первую очередь. Меньше состояний и переходов в КА - проще. Ну и не всегда, но как правило, субъективная сложность очень сильно коррелируется с объективной.


        1. a-tk
          30.01.2025 07:33

          Что-то созвучное с анекдотом "Разум на Земле - величина постоянная. А население растёт."


      1. Dhwtj
        30.01.2025 07:33

        Сложность не константа. Для того кто написал и помнит карту кода, контекст проблемы это не сложно. Когда он уйдет другим будет сложно потому что с уходом создателя код превращается в тыкву легаси.


      1. gexeg
        30.01.2025 07:33

        Откуда у вас цифра, что сложность всегда константа? Что такое сложность тогда?

        Сразу вас направлю к теории автоматов. И к иследованиям про сложность (например, what makes rules complex)

        Сделайте любой запрос по сети с использованием какойто библиотеки (нр request в питоне)? Сложно? А теперь представьте сколько деталей от вас скрыли, в том числе благодаря ооп, чтобы реально сделать такой запрос. Сможете перечислить сколько всего происходит при вызове?


    1. breninsul
      30.01.2025 07:33

      С ООП головного мозга сложность - вообще не проблема, что и показал автор.

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

      В общем-то слепое следование догматам никогда ни к чему хорошему не приведёт


      1. ScratchBoom
        30.01.2025 07:33

        Я такое в основном встречал в сгенерённом коде в библиотеках для AWS


      1. a-tk
        30.01.2025 07:33

        А Вы уверены, что то решение не было написано чьей-то кровью на стене?


    1. SpiderEkb
      30.01.2025 07:33

      Здесь скорее приведены примеры того, как не нужно добавлять сложностей там, где их не должно быть.

      Я сам отнюдь не против ООП (и пользуюсь), но там, где оно помогает "упрощать сложности". Но бывают и обратные ситуации, когда ООП "не ложится на логику процесса" и вместо упрощения приведет к неоправданному усложнению. Вот такие ситуации надо понимать и не зацикливаться только на ООП, но выбирать иные, более подходящие, парадигмы.


    1. Ritan
      30.01.2025 07:33

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


    1. Dhwtj
      30.01.2025 07:33

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

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


      1. SpiderEkb
        30.01.2025 07:33

        ООП хорошо только когда объект моделирует что-то в реальном мире

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

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

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


        1. Dhwtj
          30.01.2025 07:33

          Ещё замечу что ООП склонно к переусложнению, трудно рефакторить и в итоге быстро превращается либо в большой кусок грязи либо (из-за этих ваших паттернов) в hello world enterprise edition


    1. PlatinumKiller
      30.01.2025 07:33

      Это советы бля решения, согласен, но часто увы бездумно их применяют и бездумно их требуют.


      1. Dhwtj
        30.01.2025 07:33

        Оговорка по Фрейду


  1. ednersky
    30.01.2025 07:33

    Спасибо за статью. Давно хочу точно такую написать про типы и хейтинг исключений, которые, увы, "всё заполонили", но пока руки так и не дошли.


    1. pawnhearts
      30.01.2025 07:33

      Да, есть альтернативные подходы, которые, часто, оказываются удобней https://returns.readthedocs.io/en/latest/pages/quickstart.html

      Дальше начинаем смотреть на всякие https://github.com/ebonnal/streamable потом https://github.com/tobgu/pyrsistent https://github.com/miiohio/ziopy?tab=readme-ov-file и хочется менять язык))


  1. Juzujka
    30.01.2025 07:33

    Хорошо бы и промпт для ChatGPT приложить. Мы же на Хабре, интересуемся исходниками.


    1. avshkol
      30.01.2025 07:33

      Универсальный ответ в 2025 году и далее: ))))

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

      Промпт:

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

      1. Симптомы болезни:

        • Чрезмерное использование паттернов проектирования даже в простых задачах.

        • Отрицание процедурного и функционального программирования.

        • Превращение каждой функции в метод класса, даже если это не нужно.

      2. Примеры кода:

        • Простой код, который больной переписывает с использованием паттернов (например, замена простого условия на стратегию).

        • Пример переписывания простой функции сложения чисел в сложную иерархию классов.

      3. Методы лечения:

        • Шоковая терапия (например, написание кода на чистом C или Go).

        • Введение в рацион функционального программирования (Haskell, Elixir).

        • Чтение кода известных программистов, которые ценят простоту.

        • Временный запрет на использование DI-контейнеров и фабрик.

        • Написание простых процедурных скриптов для осознания их эффективности.

      4. Прогноз:

        • В лёгких случаях пациенты могут вернуться к нормальному программированию.

        • В тяжёлых случаях остаются архитекторами на Java и требуют рефакторинга даже у домашнего ToDo-списка.

      5. Заключение:

        • Подчеркни, что "ООП головного мозга" – это опасное расстройство, приводящее к избыточной сложности кода.

        • Добавь шутку о том, что если коллега пишет адаптер для вывода "Hello, World!", то нужно срочно вызывать специалиста.

      6. P.S.:

        • Упомяни, что текст написан ChatGPT, но он настолько хорош, что им стоит поделиться.

      7. Опрос:

        • Добавь шуточный опрос в конце: "Действительно ли существует такая болезнь?" с вариантами ответов:

          • Да, иногда встречаюсь.

          • Я сам тяжело болен.

          • Автор просто не понимает ООП и не знает паттернов проектирования, пытаясь казаться умнее других!!!

      Этот промпт должен помочь сгенерировать статью в нужном стиле.


      1. tolyanski
        30.01.2025 07:33

        промпт размером почти как сама статья))


      1. stanislavskijvlad
        30.01.2025 07:33

        Получилось очень похоже.

        Отличия

        Симптомы болезни:

        1. Паттернизация всего и вся: ОГМ проявляется в виде маниакального стремления применить паттерны проектирования в каждой, даже самой простой задаче. Больной с ОГМ не напишет простой цикл – он реализует итератор. Ему не нужно условие if, ему нужна стратегия!

        2. ООП-фундаментализм: Наблюдается стойкое отрицание процедурного и функционального программирования. Любые попытки убедить пациента в преимуществах других подходов встречают категорическое сопротивление и аргумент “но это же не ООП!”.

        3. Методизация всего: Любая функция, даже предназначенная для единичного действия, автоматически становится методом класса. “Почему бы не сделать класс Printer с методом printMessage?” - спрашивает больной, в то время как простой print("message") был бы в разы лаконичнее.

        class AgeCheckStrategy:
        def check(self, age):
        pass

        class AdultStrategy(AgeCheckStrategy):
        def check(self, age):
        if age >= 18:
        return "Совершеннолетний"

        class MinorStrategy(AgeCheckStrategy):
        def check(self, age):
        if age < 18:
        return "Несовершеннолетний"

        class AgeChecker:
        def init(self, strategy):
        self._strategy = strategy

        def check_age(self, age):    return self._strategy.check(age)
        

        age_checker = AgeChecker(AdultStrategy()) # А если нужно будет для пенсионеров? А для школьников?
        result = age_checker.check_age(19)

        Хотелось бы увидеть результат этого промта от Deep Seek.