(Объектно-Ориентированное Помешательство)
Описание:
Заразное ментальное расстройство, поражающее программистов, чрезмерно увлекающихся объектно-ориентированным программированием (ООП) и паттернами проектирования. Симптомы включают неспособность писать простой код, чрезмерное усложнение архитектуры и патологическую потребность во внедрении фабрик, стратегий и синглтонов даже там, где они не нужны.
Симптомы:
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, но он настолько хорош, что не мог не поделиться ))
Комментарии (123)
dv0ich
30.01.2025 07:33Слепое фанатичное следование чему угодно - даже самой Лучшей, Доброй и Гениальной концепции - порождает только проблемы, дичь, трэш и угар.
На мой взгляд, главное свойство зрелого человека - умение осознанно и интуитивно определять оптимальный баланс различных качеств, и не вестись на тренды и хайпы.
У каждой медали есть обратная сторона и это надо бы учитывать.
soul-catcher
30.01.2025 07:33Какой-либо паттерн предназначен для решения определённой проблемы. Решаемая проблема является частью самого паттерна. Без неё он не может существовать.
В примерах кода я не увидел ни одного применения паттерна.
А так это выглядит как мартышка и очки. "Очки не всегда полезны, потому что их применимость ограничена и многие их зря фанатично применяют".
То есть, треш и угар порождается не при слепом следовании какой-либо лучшей, доброй и гениальной концепции, а при следовании искажённому представлению о концепции в голове. Обратная сторона или же применимость является частью концепции, а не находится где-то снаружи.
UPD: поэтому мой голос за то, что автор не понимает ООП и не знает паттернов проектирования.
a-tk
30.01.2025 07:33ООП, ФП с монадами, SOLID и прочие практики нужны для того, чтобы в первую очередь управлять сложностью. И они не приносят пользы при отсутствии сложности. Поэтому нет смысла приводить примеры, где нет сложности - они будут абсурдными. Что и получилось в этой статье.
ionicman
30.01.2025 07:33Проблемы 3:
Это не управление сложностью, а перекладывание ее по разным ящикам, ибо сложность - это всегда константа, это понимаешь с опытом - т.е. что-то дает возможность просто сделать одно, в тоже время дает сложность сделать что-то другое - утрированный пример - сделал все по всем лучшим принципам - хорошо расширяется, тестируется, мокится - но вместо 1 файла получил 15 с хитрой связкой компонент и вложенности их друг в друга, и новый дев вникает в это месяц, а сам ты, вернувшись в свой код через год - два :)
Попытка использовать везде одни и теже инструменты и подходы. Типа: "ООП и СОЛИД хорошо - везде про это написано, давайте и тут запилим" - а там одна функция из 10 строк во временном скрипте, который один раз в жизни должен выполнится для получения временых данных, которые будут использованы один раз - зато круто и расширяемо и по бест практис :)
Большинcтво компонентов софта не живет больше 1-2 лет, за исключением энтерпрайза и некоторых других исключений, не надо думать и закладывать туда все возможное и делать максимально универсально, нужно всегда делать балансируя между достаточной универсальностью и простотой - и именно это и есть золотая грань, которую да - очень сложно держать. Не надо бояться переписывать и рефакторить - иногда проще и быстрее переписать компонент с нуля на современном фрейморке и в современной парадигме, учтя опыт его текущего использования и контекста, чем пытаться патчить/расширять существующий.
Ну и, всегда стоит помнить статью "Вы - не Гугл" :)
tolyanski
30.01.2025 07:33Большинcтво компонентов софта не живет больше 1-2 лет
эт конечно вы загнули) БОЛЬШИНСТВО компонентов живет 5-10-15 лет, к сожалению...
Не надо бояться переписывать
пока по башке не получили от продакта или собственника бизнеса
a-tk
30.01.2025 07:33Ох, доводилось мне видеть компоненты, которые писали джуны "на один раз", которые (джуны в смысле) сбегали через годика полтора-два. Собственно, если ты раз в два года меняешь работу в очередной стартап, то не просто успеваешь застать долгоживующие компоненты.
pes_loxmaty
30.01.2025 07:33Это не управление сложностью, а перекладывание ее по разным ящикам
Так ведь divide et impera
Вам вероятно не попадались проекты такого размера, что он не может уместиться целиком в голове одного человека (ну во всяком случае новичек в команде не сможет преисполниться за вменяемое время)
Nipheris
30.01.2025 07:33Большинcтво компонентов софта не живет больше 1-2 лет, за исключением энтерпрайза и некоторых других исключений, не надо думать и закладывать туда все возможное и делать максимально универсально.
Тут что-то на фронтэндерском, не получается прочитать.
mitix
30.01.2025 07:33Про "сложность - это всегда константа", честно говоря не понял, что это значит?
Dhwtj
30.01.2025 07:33Сложность не константа. Для того кто написал и помнит карту кода, контекст проблемы это не сложно. Когда он уйдет другим будет сложно потому что с уходом создателя код превращается в
тыквулегаси.
breninsul
30.01.2025 07:33С ООП головного мозга сложность - вообще не проблема, что и показал автор.
Неужели вы не видели примеров, когда нужно создать фабрику через билдер, в фабрику передать аргументы каждый своим билдером, а результатом будет новый билдер, который надо передать...
В общем-то слепое следование догматам никогда ни к чему хорошему не приведёт
SpiderEkb
30.01.2025 07:33Здесь скорее приведены примеры того, как не нужно добавлять сложностей там, где их не должно быть.
Я сам отнюдь не против ООП (и пользуюсь), но там, где оно помогает "упрощать сложности". Но бывают и обратные ситуации, когда ООП "не ложится на логику процесса" и вместо упрощения приведет к неоправданному усложнению. Вот такие ситуации надо понимать и не зацикливаться только на ООП, но выбирать иные, более подходящие, парадигмы.
Ritan
30.01.2025 07:33Проблема в том, что слепое следование принципам само по себе создаёт сложность. В результате для управления этой сложностью приходится добавлять ещё больше сложности. И так до победного конца
Dhwtj
30.01.2025 07:33Не столько управление сложностью, сколько изоляция одного куска кода от другого, а одного программиста от другого. И вот изоляция в ООП очень неудобна, тяжеловесна. А если границы абстракций надо перенести превращается в ужас.
ООП хорошо только когда объект моделирует что-то в реальном мире. Когда появляется руководитель отдела сусликов, который уточняет задания и ставит им задачи, то это фабрика. Но обычно в реальном мире такой фигнёй не маются.
ednersky
30.01.2025 07:33Спасибо за статью. Давно хочу точно такую написать про типы и хейтинг исключений, которые, увы, "всё заполонили", но пока руки так и не дошли.
Juzujka
30.01.2025 07:33Хорошо бы и промпт для ChatGPT приложить. Мы же на Хабре, интересуемся исходниками.
avshkol
30.01.2025 07:33Универсальный ответ в 2025 году и далее: ))))
Вот пример промпта, который можно использовать для генерации подобной статьи:
Промпт:
Напиши юмористическую статью в стиле медицинского анализа о "болезни" под названием "ООП головного мозга". Описывай симптомы, примеры кода и методы лечения. Статья должна быть сатирической, но при этом содержать реальные примеры из мира программирования. Включи следующие разделы:
-
Симптомы болезни:
Чрезмерное использование паттернов проектирования даже в простых задачах.
Отрицание процедурного и функционального программирования.
Превращение каждой функции в метод класса, даже если это не нужно.
-
Примеры кода:
Простой код, который больной переписывает с использованием паттернов (например, замена простого условия на стратегию).
Пример переписывания простой функции сложения чисел в сложную иерархию классов.
-
Методы лечения:
Шоковая терапия (например, написание кода на чистом C или Go).
Введение в рацион функционального программирования (Haskell, Elixir).
Чтение кода известных программистов, которые ценят простоту.
Временный запрет на использование DI-контейнеров и фабрик.
Написание простых процедурных скриптов для осознания их эффективности.
-
Прогноз:
В лёгких случаях пациенты могут вернуться к нормальному программированию.
В тяжёлых случаях остаются архитекторами на Java и требуют рефакторинга даже у домашнего ToDo-списка.
-
Заключение:
Подчеркни, что "ООП головного мозга" – это опасное расстройство, приводящее к избыточной сложности кода.
Добавь шутку о том, что если коллега пишет адаптер для вывода "Hello, World!", то нужно срочно вызывать специалиста.
-
P.S.:
Упомяни, что текст написан ChatGPT, но он настолько хорош, что им стоит поделиться.
-
Опрос:
-
Добавь шуточный опрос в конце: "Действительно ли существует такая болезнь?" с вариантами ответов:
Да, иногда встречаюсь.
Я сам тяжело болен.
Автор просто не понимает ООП и не знает паттернов проектирования, пытаясь казаться умнее других!!!
-
Этот промпт должен помочь сгенерировать статью в нужном стиле.
stanislavskijvlad
30.01.2025 07:33Получилось очень похоже.
Отличия
Симптомы болезни:
Паттернизация всего и вся: ОГМ проявляется в виде маниакального стремления применить паттерны проектирования в каждой, даже самой простой задаче. Больной с ОГМ не напишет простой цикл – он реализует итератор. Ему не нужно условие
if
, ему нужна стратегия!ООП-фундаментализм: Наблюдается стойкое отрицание процедурного и функционального программирования. Любые попытки убедить пациента в преимуществах других подходов встречают категорическое сопротивление и аргумент “но это же не ООП!”.
Методизация всего: Любая функция, даже предназначенная для единичного действия, автоматически становится методом класса. “Почему бы не сделать класс
Printer
с методомprintMessage
?” - спрашивает больной, в то время как простойprint("message")
был бы в разы лаконичнее.
class AgeCheckStrategy:
def check(self, age):
passclass 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 = strategydef check_age(self, age): return self._strategy.check(age)
age_checker = AgeChecker(AdultStrategy()) # А если нужно будет для пенсионеров? А для школьников?
result = age_checker.check_age(19)Хотелось бы увидеть результат этого промта от Deep Seek.
-
kalbas
Если не брать то, что примеры немного утрированы, и некоторые упомянутые вещи (например SOLID это далеко не всегда про ООП, скорей про общую организацию кода), в целом статья великолепна. Я недавно сменил место работы и тут DI завезен по полной и все перекрыто иерархиями в микросервисе из одной ручки, нахожусь в перманентном удивлении и пока еще так и не понял, что происходит.