Почему JS с первых уроков дает фундамент проектирования, а Python — нет
Это мое личное мнение, основанное на опыте обучения. Проблема не в самом языке — Python великолепен. Проблема в том, как его изучают. То, что в JavaScript новичок понимает на первых двух уроках, в Python многие не осознают даже после продвинутых курсов по ООП. А ведь именно это понимание является фундаментом любой архитектуры.
Проблема Python: Класс как «пустой контейнер»
В Python большинство курсов годами фокусируются на синтаксисе: типах данных, циклах и бесконечных манипуляциях со списками. В итоге человек выходит из обучения с багажом знаний о том, «как написать цикл», но без малейшего понимания, «как построить проект».
Когда же дело доходит до ООП, новичок часто пишет код вот так:
class Player:
name = 'Alex'
health = 100
class Enemy:
name = 'Orc'
health = 100
def damage(obj):
obj.health -= 20
# Ошибка, которую новичок не замечает:
damage(Enemy)
print(Enemy.health)
Важное уточнение: Да, я умышленно нарушил здесь принципы работы с классами, не стал использовать
initи экземпляры. Я сделал это специально, чтобы максимально приблизить пример к JS и показать суть: новичок видит словоclass, но фактически использует его просто как контейнер переменных.
Новичок видит ключевое слово class, но фактически работает не с объектом, а с самим классом как с глобальным контейнером переменных. В этом кроется архитектурная катастрофа:
Смерть инкапсуляции: Мы изменили не конкретного орка, а саму «концепцию» всех орков в игре (атрибут класса). Заметили? Мы сломали всех будущих врагов сразу. В реальном проекте такая ошибка создаст непредсказуемое глобальное состояние, которое можно отлаживать неделями.
Отсутствие понимания состояния: Новичок не чувствует разницы между «чертежом» (классом) и «живым объектом» (экземпляром) в памяти.
Класс как «удобный словарик»: Для него это просто способ сгруппировать
nameиhealth, чтобы не передавать их в функцию по отдельности.
Ловушка словарей (The Dictionary Trap)
Если новичку кажется, что классы — это «слишком сложно», он падает в другую ловушку — использование обычных словарей (dict) для моделирования всего на свете.
enemy = {"name": "Orc", "health": 100}
def damage(obj):
obj["health"] -= 20
Словарь кажется удобным, но это яд для архитектуры:
Словарь не гарантирует структуру: Ты не знаешь, есть ли там ключ
"health", пока программа не упадет сKeyErrorв самый неподходящий момент.Зависимость от «магических строк»: Ваша бизнес-логика начинает зависеть от того, не опечатался ли кто-то в строке
"health".Отсутствие контракта: Функция, принимающая словарь, — это «черный ящик» с кучей надежд. Архитектура же строится на жестких обязательствах (контрактах), которые словарь предоставить не может.
В итоге программа превращается в конвейер, где функции отдельно, а данные (словари) — отдельно. Это «спагетти-процедуры», которые рассыпаются при малейшем изменении.
Как это выглядит в JS: Объект как единица смысла
В JavaScript новичок с самого начала работает с объектами напрямую, минуя сложные абстракции. Важно понимать: в данном примере это не класс, а тип данных «объект». Это работает так, как если бы в Python мы сразу создали готовый экземпляр (объект в памяти), пропустив этап описания чертежа-класса. Новичку не нужно объяснять, что такое «чертеж», чтобы он создал «вещь».
const Player = {
name: "Alex",
health: 100
}
const Enemy = {
name: "Orc",
health: 100
}
function damage(obj) {
obj.health -= 20
}
damage(Enemy)
console.log(Enemy.health)
В JS на старте объект — это всегда живая сущность. Здесь нет путаницы между классом и экземпляром на первых порах. Новичок сразу хватает базу:
Объект = Данные + Поведение.
Объект — это ссылка: Его можно передать в функцию, изменить, и это изменение будет локальным и предсказуемым (как если бы мы передали конкретный экземпляр в Python).
Объект — это единица структуры: Ты приучаешься к мысли, что данные не «болтаются» сами по себе в глобальных переменных или случайных списках, они всегда принадлежат конкретной сущности.
Это и есть зачатки архитектурного мышления. JS-разработчик «из коробки» привыкает к фундаментальной идее: «Данные и поведение должны быть связаны в рамках одной единицы».
Когда ты создаешь сущность, ты начинаешь думать о её границах. Ты не просто меняешь цифру в словаре, ты взаимодействуешь с «живым» игроком или врагом. В этом и есть коренное отличие архитектурного подхода от простого «перекладывания данных».
Почему это критично для архитектуры?
Архитектура начинается там, где мы определяем границы и контракты.
В процедурном подходе (Python-словари) вы сами лезете «внутри» врага и меняете ему цифры. Вы знаете слишком много о его внутренностях.
В архитектурном подходе вы не меняете данные напрямую. Вы просите объект «принять урон», и он сам решает, как это сделать (учитывая броню, щиты или уклонение).
Когда вы привыкаете, что данные — это просто куча записей в словаре, вы создаете связи, которые невозможно разорвать. При добавлении любого нового параметра (например, «защиты») вам придется переписывать десятки функций-манипуляторов во всех модулях проекта.
Итог
Почти ни один базовый курс по Python не учит моделировать сущности и строить структуру проекта. Пока Python-разработчик перекладывает данные из одного словаря в другой, плодя зависимости от магических строк, JS-разработчик уже мыслит категориями взаимодействующих объектов.
В рамках этого курса мы будем исправлять эту ситуацию:
Уйдем от «пустых контейнеров»: Мы научимся превращать Python-классы из «красивых словарей» в защищенные сущности с четким состоянием.
Защитим поведение: Мы научимся проектировать объекты так, чтобы их внутреннее состояние нельзя было сломать случайным вызовом.
Построим систему, а не скрипт: Мы будем собирать программу из независимых блоков, которые общаются через строгие интерфейсы, а не через общие словари.
Цель — перестать писать «код, который просто работает», и начать проектировать системы, которые легко развивать. Именно этому и посвящена Чистая Архитектура.
Я сделал бесплатный курс по архитектуре на python, кому интересно можете изучить по ссылке.