React: Что такое композиция и почему она важна


Что такое композиция

Позвольте мне продемонстрировать это на небольшом примере:

// no composition
<AlertDialog
  open={true}
  title="Don't use composition!"
/>

// with composition
<Dialog open={true}>
  <Title>Don't use composition!</Title>
  <Button>Close</Button>
</Dialog>
Вход в полноэкранный режим Выход из полноэкранного режима

На первый взгляд первый пример кажется хорошей идеей, верно? Он короче, и вы полностью спрятали компонент кнопки внутри AlertDialog, так что вам больше не нужно о нем беспокоиться!

Но теперь нам нужен другой специальный диалог оповещения, который может иметь svg иконку в заголовке! Это означает, что мы должны изменить интерфейс AlertDialog, чтобы заголовок мог принимать либо string, либо ReactNode.

// no composition
<AlertDialog
  open={true}
  title={<><SvgAlertIcon /> Don't use composition!</>}
/>

// with composition
<Dialog open={true}>
  <Title><SvgAlertIcon /> Don't use composition!</Title>
  <Button>Close</Button>
</Dialog>
Вход в полноэкранный режим Выход из полноэкранного режима

Или еще хуже, теперь клиент также хочет специальный диалог оповещения (диалог подтверждения), в котором есть кнопки «отмена» и «ок». Это означает, что нам придется сильно изменить код внутри AlertDialog и поместить туда условную логику, чтобы он мог отображать либо кнопку «закрыть», либо кнопки «отмена» и «ок».

// no composition
<AlertDialog
  open={true}
  title="Are you sure you don't want to use composition?"
  asConfirmationDialog
/>

// with composition
<Dialog open={true}>
  <Title>Are you sure you don't want to use composition?</Title>
  <Button>Cancel</Button>
  <Button>Ok</Button>
</Dialog>
Вход в полноэкранный режим Выйти из полноэкранного режима

Вы можете себе представить, что код внутри AlertDialog будет усложняться со временем по мере того, как будут поступать запросы на дополнительные возможности, в то время как в композиции НИ ОДИН из компонентов не изменился внутренне.

Почему композиция важна

Из приведенного выше примера вы уже видите, что композиция важна, потому что без нее сложность наших компонентов будет расти экспоненциально со временем, пока они не станут непригодными для использования. Но неиспользование композиции в React также нарушает некоторые хорошо известные принципы, которые вы можете помнить из объектно-ориентированного программирования (принципы SOLID).

Единая ответственность

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

Принцип открытости/закрытости

Нарушение принципа «открыто/закрыто» можно применить и к компонентам React. Нам необходимо внести изменения во внутреннюю логику компонента AlertDialog, если мы хотим его расширить (он должен быть закрыт для модификации и открыт для расширения).


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

Оцените статью
devanswers.ru
Добавить комментарий