92 lines
8.8 KiB
Markdown
92 lines
8.8 KiB
Markdown
---
|
||
sidebar_position: 9
|
||
---
|
||
|
||
# SOLID
|
||
|
||
SOLID в React помогает:
|
||
- Держать компоненты маленькими и читаемыми (S).
|
||
- Делать их расширяемыми через props и композицию (O).
|
||
- Гарантировать предсказуемость работы компонентов (L).
|
||
- Избегать перегруженных пропсов и интерфейсов (I).
|
||
- Упрощать замену реализаций (API, стейт-менеджер и т.д.) через абстракции (D).
|
||
|
||
Принципы SOLID — это набор из пяти ключевых принципов объектно-ориентированного программирования и проектирования, которые помогают создавать гибкие, поддерживаемые и масштабируемые программные системы. Аббревиатура SOLID была введена Робертом Мартином (известным также как Uncle Bob) и расшифровывается следующим образом:
|
||
|
||
## Simple responsibility principle (принцип единой ответственности)
|
||
У класса должна быть только одна причина для изменения, то есть у него должна быть только одна ответственность или работа. Этот принцип помогает сделать занятия более целенаправленными, более понятными и менее подверженными ошибкам.
|
||
|
||
**Применение во Фронтенде:** Каждый компонент/модуль должен выполнять одну задачу.
|
||
В React:
|
||
- Компонент выполняет **одну задачу**: либо отображает UI, либо управляет состоянием, но не всё сразу.
|
||
- Логика выносится в **хуки** или **сервисы**, чтобы компоненты оставались "чистыми".
|
||
|
||
Пример:
|
||
- ❌ Плохо: `UserProfile` компонент, который извлекает, проверяет, отображает и управляет состоянием.
|
||
- ✅ Хорошо: `UserProfile` компонент, который только отображает, и отдельный хук (`useUser`), который извлекает данные.
|
||
|
||
## Open – Closed Principle (Принцип открытости/закрытости)
|
||
Программные сущности должны быть открыты для расширения, но закрыты для модификации. Это означает, что вы должны иметь возможность добавлять новые функции в систему, не изменяя существующий код.
|
||
Мы можем расширить функциональный компонент и добавить новый компонент пользовательского интерфейса, не затрагивая первый/базовый компонент. Это реализация открытости для расширения, но закрытости для модификации.
|
||
|
||
**Применение во Фронтенде:** Код должен быть расширяемым без переписывания старой логики.
|
||
- Используем **props** для настройки поведения.
|
||
- Применяем **композицию** вместо жёсткого наследования.
|
||
|
||
Вместо того, чтобы переписывать старые компоненты, проектируйте их так, чтобы можно было добавлять новые функции с помощью свойств/хуков/расширений.
|
||
Пример: Хотите добавить новый стиль кнопки? Добавьте свойство для расширения стилей, не дублируйте весь компонент.
|
||
|
||
|
||
## Liskov Substitution principe (принцип замены Лискова)
|
||
Объекты суперкласса должны быть заменяемы объектами его подклассов без нарушения корректности программы. Другими словами, подклассы должны иметь возможность заменять свои базовые классы без возникновения ошибок.
|
||
|
||
**Применение во Фронтенде:** Кнопка `Button` всегда должна действовать как кнопка, независимо от того, является ли она основной, дополнительной или отключенной.
|
||
|
||
В React:
|
||
- Это проявляется в **контрактах компонентов**: если компонент принимает `props`, он должен работать предсказуемо для любого допустимого значения.
|
||
- Не заставляй компонент вести себя неожиданно из-за "хаков" или скрытой логики.
|
||
|
||
## Interface segregation principle (Принцип разделения интерфейсов)
|
||
Клиентов не следует заставлять зависеть от интерфейсов, которые они не используют. Вместо этого интерфейсы следует разделить на более мелкие, более целенаправленные интерфейсы, соответствующие потребностям клиента.\
|
||
Лучше много маленьких интерфейсов, чем один "толстый".
|
||
|
||
**Применение во Фронтенде:** Не заставляйте компоненты принимать свойства, которые они не используют.
|
||
- ❌ Плохо: Много лишних свойств в компоненте, 80% которого не используется.
|
||
- ✅ Хорошо: Используйте только те свойства которые используются в компоненте.
|
||
|
||
В React:
|
||
- Не перегружай компонент кучей пропсов.
|
||
- Делай узко специализированные пропсы или выноси сложные конфигурации в отдельные структуры.
|
||
|
||
Пример: Вместо `user: {id, name, email, role, lastLogin, preferences}`, возможно, вам для UserAvatar нужны только `name` и `profilePic`.
|
||
```js
|
||
// ❌ Плохо: слишком много пропсов
|
||
<Card title subtitle image footer isLoading isActive hasError />
|
||
|
||
// ✅ Лучше: разделяем интерфейсы
|
||
<Card>
|
||
<CardHeader title="..." subtitle="..." />
|
||
<CardBody>...</CardBody>
|
||
<CardFooter>...</CardFooter>
|
||
</Card>
|
||
```
|
||
|
||
## Dependency inversion principle (Инверсия зависимости)
|
||
Высокоуровневые модули не должны зависеть от низкоуровневых модулей. Вместо этого, оба должны зависеть от абстракций. Это помогает в разъединении модулей, делая их более пригодными для повторного использования и более простыми для тестирования.
|
||
|
||
**Применение во Фронтенде:** Опирайтесь на абстракции, а не на детали.
|
||
- Вместо жесткого задания функций API в компонентах внедрите сервисный уровень.
|
||
- Если завтра ваш API изменится, вы меняете логику сервиса, а не всё приложение.
|
||
|
||
В React:
|
||
- Используем контекст или hooks для работы с зависимостями (например, API или хранилище).
|
||
- Компоненты не должны жёстко зависеть от конкретной реализации.
|
||
|
||
## Преимущества SOLID:
|
||
1. **Гибкость:** Код становится проще расширять и модифицировать.
|
||
2. **Поддерживаемость:** Упрощается понимание и исправление ошибок.
|
||
3. **Тестируемость:** Код, соответствующий SOLID, легче тестировать.
|
||
4. **Масштабируемость:** Система становится более устойчивой к изменениям и росту.
|
||
|
||
🚀 **_Источник: ChatGPT_**
|