refactor: move big from n to arch
This commit is contained in:
91
docs/architecture/09-solid.md
Normal file
91
docs/architecture/09-solid.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
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_**
|
||||
Reference in New Issue
Block a user