Пирамидальная схема компонентов React: кризис чрезмерного проектирования

В какой-то момент мы перестали писать компоненты React и начали им поклоняться. Мантра «многоразового использования» превратилась из передовой практики в полноценную теологию.

В каждой команде есть один инженер, проповедующий евангелие Ultimate Component — тот, который может справиться с любым макетом, цветовой схемой и крайним случаем с дюжиной дополнительных реквизитов и 500 строками условий.

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

Культ повторного использования компонентов

Разработчики любят элегантность. Мы жаждем шаблонов, которые заставляют нас чувствовать, что мы преодолели хаос специального кодирования. DRY («Не повторяй себя») стал одним из этих священных принципов — простая идея, превратившаяся в догму. Вместо того чтобы избегать ненужного дублирования, многие команды начали избегать любого дублирования, чего бы это ни стоило. Результат? Абстрактные чудовища, которые делают тысячу вещей плохо вместо трёх вещей хорошо.

Одержимость возможностью повторного использования часто приводит к «супу из реквизита».

Одержимость возможностью повторного использования часто приводит к «супу реквизита»: компоненты перегружены реквизитами, чтобы справиться со всеми возможными вариациями. Вы увидите компоненты Button, которые допускают 20 параметров, позволяющих лишь слегка настроить отступы или выравнивание значков. Вместо того, чтобы упрощать разработку, эти компоненты усложняют работу в масштабе. Отладка превращается в археологию: разработчики просеивают уровни абстракции, пытаясь выяснить, почему кнопка выглядит неправильно в одном контексте, но хорошо в другом.

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

Когда принцип DRY приводит к сложности

Принцип DRY прекрасен в теории, но ненадежен на практике. Дублирование кода не всегда является злом; иногда это просто прагматично. Чрезмерная абстракция может лишить код контекста, что усложнит его размышление. Несколько дополнительных строк повторения часто обходятся дешевле, чем месяц, потраченный на расшифровку лабиринта многократно используемой логики. Не будьте рабами показателей, ребята. Заставьте их работать на вас.

Представьте себе две формы в вашем приложении: форму входа и форму регистрации. Они имеют некоторые общие входные данные, но имеют разную логику проверки и потоки отправки. Фанатик DRY объединяет их в один мегакомпонент с десятком условных ветвей. Теперь каждое небольшое изменение рискует нарушить оба потока. Исходные два простых компонента слились в гидру операторов if.

Ключ не в том, чтобы повторяться бесконечно, а в том, чтобы знать, когда повторное использование перестает быть эффективным и начинает запутывать.

Хорошая инженерия – это баланс. СУХОЙ должен сосуществовать с другим, менее известным принципом: ВЛАЖНЫЙ — пишите все дважды. Дублирование, если оно сделано намеренно, сохраняет ясность. Это позволяет коду развиваться независимо.

Ключ не в том, чтобы повторяться бесконечно, а в том, чтобы знать, когда повторное использование перестает быть эффективным и начинает запутывать. Модель компонентов React достаточно гибка, чтобы допускать некоторое дублирование. Проблема в том, что разработчики относятся к дублированию как к греху, а не к стратегии.

Перепроектированная кнопка: практический пример

Давайте поговорим о Button.jsx, неофициальном талисмане чрезмерного проектирования. Он всегда здесь, скрывается в каждом проекте React. Все начинается с простого: многоразовая кнопка с цветом и меткой. Тогда кому-то нужна икона. Кому-то еще нужно состояние загрузки.

Затем он должен поддерживать ссылки, отключенные состояния, вложенные компоненты, темы и пользовательские обработчики кликов. Вскоре у Button.jsx появилось дюжина реквизитов, изобилие условного рендеринга и список propType, длиннее, чем сам компонент.

Каждого нового разработчика предупреждают: «Не трогайте Button.jsx». Тем не менее, все так делают.

Каждого нового разработчика предупреждают: «Не трогайте Button.jsx». Тем не менее, все так делают, потому что каждая новая функция требует еще одной настройки. В конце концов абстракция рушится под действием собственной гибкости. Тестирование становится болезненным, потому что вы фактически тестируете 10 различных компонентов, объединенных в один файл. Документация отстает, и то, что началось как благородная попытка повторного использования, теперь снижает производительность.

На этом этапе команды начинают отламывать осколки — создавая SlightlyDifferentButton.jsx или IconButton.jsx. По иронии судьбы, противоядием от чрезмерного повторного использования является дублирование. База кода возвращается в состояние, которое на самом деле становится более удобным в обслуживании, поскольку каждая кнопка теперь хорошо выполняет одну задачу. Мораль: повторное использование должно служить ясности, а не наоборот.

Опасности преждевременной абстракции

Миф о повторном использовании возникает из-за непонимания того, что делает код поддерживаемым. Дело не в том, сколько строк вы написали и сократили ли вы затраты на облако, а в том, как мало умственных прыжков требуется, чтобы понять, что происходит. Каждая абстракция добавляет уровень косвенности, и каждый уровень требует когнитивных усилий. Проблема не в том, что мы абстрагируемся; дело в том, что мы преждевременно абстрагируемся — прежде чем по-настоящему поймем проблемную область.

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

Разработчики часто делают обобщения слишком рано, потому что это кажется эффективным. «Наверное, нам это понадобится в другом модуле», — говорит кто-то, и вдруг одноцелевой хук становится утилитой с пятью параметрами и двумя поставщиками контекста. Но абстракция без доказанного повторного использования не является предвидением; это спекуляция. А спекулятивные абстракции — один из самых трудных для удаления кода, поскольку когда-нибудь они все равно могут пригодиться.

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

Принятие подхода после повторного использования для архитектуры React

Нам нужна культурная перезагрузка того, как выглядит «хорошая» архитектура React. Одержимость отрасли DRY, универсальными компонентами и абстракциями высокого уровня привела к созданию хрупких систем, которые выглядят элегантно, но легко ломаются. Настоящая ремонтопригодность заключается не в том, сколько строк вы можете использовать совместно, а в том, насколько легко рассуждать о каждой части в отдельности.

Хотите верьте, хотите нет, но дублирование не означает возврата к хаосу. Это означает уважение границ, сохранение кода ближе к его контексту и признание того, что локальная оптимизация часто лучше глобальной чистоты. На практике это может означать наличие трех разных компонентов формы, которые выглядят на 80% похожими, но которые легко модифицировать независимо друг от друга. Это может означать удаление «служебной» функции, которая использовалась только дважды. Это может даже означать удаление универсального Button.jsx и начало заново.

Где-то по пути мы заменили простоту поклонением абстракции.

React был построен на идее небольших составных частей. Где-то по пути мы заменили эту простоту поклонением абстракции. Пришло время заново открыть для себя радость простого, читаемого, контекстно-зависимого кода. Лучший компонент — это не тот, который можно использовать повсюду, а тот, который можно понять мгновенно.

Простые, автономные компоненты

Экосистеме React не нужно больше повторно используемых компонентов и методов для их хранения. Нужны более целенаправленные действия. Стремление к повторному использованию само по себе привело к появлению поколения кодовых баз, которые теоретически элегантны, но практически хрупки. За каждую абстракцию приходится платить, и счет всегда приходит к оплате.

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

Самые здоровые системы — это не пирамиды, построенные на уровнях абстракции; это сады простых, автономных компонентов, которые растут независимо, не подавляя друг друга. Возможно, пришло время перестать карабкаться по пирамиде и вместо этого начать подстригать сад.

ТЕНДЕНЦИОННЫЕ ИСТОРИИ YOUTUBE.COM/THENEWSTACK Технологии развиваются быстро, не пропустите ни одной серии. Подпишитесь на наш канал YouTube, чтобы смотреть все наши подкасты, интервью, демонстрации и многое другое. ПОДПИСАТЬСЯ Группа, созданная в Sketch. Александр Уильямс — полнофункциональный разработчик и технический писатель, имеющий опыт работы независимым ИТ-консультантом и помогающий новым владельцам бизнеса настраивать свои веб-сайты. Узнайте больше от Александра Т. Уильямса

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *