Принципы
Вопрос:
Расскажите, что такое SOLID?
Ответ:
SOLID — это набор пяти принципов объектно-ориентированного проектирования, которые помогают писать код, легко поддающийся поддержке, тестированию и расширению.
Принцип единственной ответственности
Каждый класс или модуль должен иметь единственную обязанность и, соответственно, единственную причину для изменения.
Принцип открытости/закрытости
Простыми словами — модули надо проектировать так, чтобы их требовалось менять как можно реже, а расширять функциональность можно было с помощью создания новых сущностей и композиции их со старыми.
Принцип подстановки Барбары Лисков
Классы-наследники не должны противоречить базовому классу. Например, они не могут предоставлять интерфейс ýже базового. Поведение наследников должно быть ожидаемым для функций, которые используют базовый класс.
Принцип разделения интерфейса
Клиенты (классы, модули) не должны зависеть от интерфейсов (или контрактов), которые они не используют. Если интерфейс «жирный» и содержит слишком много методов, лучше разбить его на несколько специализированных интерфейсов.
Принцип инверсии зависимостей
Зависимости должны строиться на уровне абстракций, а не конкретных реализаций. Модули верхнего уровня не должны зависеть от модулей нижнего уровня напрямую — оба типа модулей зависят от абстракций.
SRP – Один модуль, одна ответственность.
OCP – Открыт для расширения, закрыт для изменения.
LSP – Наследники должны быть подставляемы на место родительских типов без проблем.
ISP – Разделяйте «жирные» интерфейсы, чтобы зависимости были минимальными.
DIP – Зависите от абстракций, а не от конкретных реализаций.
S — Single Responsibility (Принцип единственной ответственности)
Каждый модуль/класс должен иметь только одну причину для изменений — решать только одну задачу.
Аналогия: класс — не швейная мастерская и не бухгалтерия одновременно.
O — Open/Closed (Открыт/Закрыт)
Код должен быть открыт для расширения (новое поведение), но закрыт для модификации (не менять старый код).
Идея: добавляем новые плагины/наследников, а не лезем в рабочий класс.
L — Liskov Substitution (Подстановка Лисков)
Подкласс должен полностью заменять базовый класс без сюрпризов для клиента.
Проще: если у тебя есть Bird, то Penguin не должен ломать ожидания, что птица умеет летать (если интерфейс требует полёта — плохо).
I — Interface Segregation (Разделение интерфейсов)
Лучше иметь много маленьких специализированных интерфейсов, чем один большой «жирный» интерфейс.
Вытекает: клиенты зависят только от того, что они реально используют.
D — Dependency Inversion (Инверсия зависимостей)
Модули высокого уровня не должны зависеть от модулей низкого уровня — оба должны зависеть от абстракций. Абстракции не должны зависеть от деталей; детали — от абстракций.
Практика: вместо new Database() передаём интерфейс IDatabase в конструктор.
Вопрос:
Расскажите, что такое DRY (Don't Repeat Yourself)?
Ответ:
Если что-то в коде нужно повторять — лучше выделить это в отдельную функцию, модуль или класс и переиспользовать.
Вопрос:
Расскажите, что такое KISS (Keep It Simple, Stupid)?
Ответ:
Основная идея заключается в том, что чем проще код, тем легче его читать, тестировать и поддерживать. Избавляйтесь от ненужных усложнений, избегайте чрезмерных абстракций и придерживайтесь логической ясности в решениях.
Вопрос:
Расскажите, что такое YAGNI (You Aren't Gonna Need It)?
Ответ:
Проще говоря, не нужно писать код и создавать инфраструктуру «на будущее», если сейчас в этом нет непосредственной необходимости.
Вопрос:
Расскажите, что такое FSD (Feature-Sliced Design) архитектура?
Ответ:
Паттерны
Вопрос:
Паттерн Абстрактная фабрика (Abstract Factory)
Ответ:
Абстрактная фабрика (Abstract Factory) — это порождающий паттерн проектирования, который предоставляет интерфейс для создания семейств взаимосвязанных объектов без указания конкретных классов.
Этот паттерн особенно полезен, когда ваш код должен работать с разными «семействами» объектов, но при этом оставаться независимым от конкретных реализаций.
Когда применять «Абстрактную фабрику»?
- Когда в программе должно существовать несколько «семейств» продуктов, которые используются совместно. Например, разные темы (Theme) в UI (светлая, тёмная) или различные движки (2D/3D).
- Когда нужно создавать объекты в зависимости от конкретной конфигурации или среды выполнения (например, Web vs. Mobile), но код не должен зависеть от деталей этой конфигурации.
- Когда нужно скрыть от клиента логику выбора конкретной реализации, чтобы её можно было легко изменить без затрагивания остального кода.
Архитектура
Вопрос:
FSD (Feature-Sliced Design) архитектура
Feature-Sliced Design (FSD) — это архитектурная методология для frontend-приложений. Проще говоря, это свод правил и соглашений по организации кода. Главная цель методологии — сделать проект понятным и структурированным, в условиях регулярного изменения требований бизнеса.
Основные концепции FSD
Разделение по слоям (slices)
App: настройки приложения, глобальные провайдеры, роутинг.
Processes: крупные бизнес-процессы, которые затрагивают всё приложение (например, онбординг пользователя или платёжный процесс).
Pages: страницы приложения с конкретным UI, маршрутами и контейнерами.
Features: отдельные пользовательские фичи (например, «добавление товара в корзину», «авторизация»).
Entities: модули с описанием и логикой «сущностей» предметной области (User, Product, Order и т.д.).
Shared: общие библиотеки, утилиты, переиспользуемые компоненты (кнопки, иконки, функции валидации).
Группировка кода по фичам
Вместо того чтобы хранить все компоненты в одной папке components/, все стили в styles/ и т.д., FSD предлагает хранить весь код, относящийся к функционалу (UI-компоненты, логику, стили, тесты), в одной фиче. Это повышает когезию (целостность) и упрощает поиск нужных файлов.
Чёткие границы ответственности
Каждый слой отвечает за свой набор задач. Например, изменения в фиче обычно не затрагивают другие фичи, поскольку общие инструменты живут в shared/, а глобальные настройки — в app/ или processes/.
Преимущества FSD
Масштабируемость
Когда в приложении появляются новые фичи или бизнес-сценарии, их добавляют как отдельные директории и модули, не затрагивая при этом структуру остальных частей.
Упрощение сопровождения
Если нужно разобраться в конкретной фиче или внести правки, разработчик видит всю логику фичи — от компонентов до стилей — в одном месте.
Модулируемость
Легко подключать или отключать конкретные фичи, перенести их в другой проект или сделать отдельным пакетом.
Минимизация конфликтов в команде
Разработчики могут параллельно вести работу над разными фичами, не мешая друг другу.
В данных примерах:
app/ содержит глобальную инициализацию и конфигурацию приложения.
processes/ включает в себя «длинные» бизнес-процессы (например, многошаговые сценарии).
pages/ — отдельные страницы (роуты).
features/ — набор фич (каждая фича содержит всё нужное для своей работы: UI, бизнес-логику и т. д.).
entities/ — описание моделей (User, Product и др.) и их поведение.
shared/ — переиспользуемые компоненты, утилиты и конфигурации.
Рекомендации по применению
Начинайте с малого: не нужно сразу насильно вводить все слои, если у вас маленькое приложение. Добавляйте слои по мере роста проекта.
Чётко определяйте границы фич: фича должна решать одну конкретную задачу (например, «управление профилем пользователя» или «добавление товара в корзину»).
Используйте именование: если структура проекта становится сложной, придерживайтесь единых правил именования директорий и файлов, чтобы не запутаться.
Следуйте принципам DRY, YAGNI и KISS: FSD — это лишь схема организации кода. Она не отменяет базовых принципов написания чистого кода и продуманной архитектуры.
Вопрос:
Atomic Design (Атомарный дизайн)
Atomic Design (Атомарный дизайн) — это методология, разработанная Брэдом Фростом (Brad Frost) для построения дизайн-систем. Её суть — разбивать интерфейс на пять уровней абстракции, начиная от простейших элементов (атомов) и заканчивая полноценными страницами. Это облегчает переиспользование и масштабирование интерфейсных компонентов.
Основные уровни Atomic Design
1
Атомы (Atoms)
Базовые элементы интерфейса: кнопки, ссылки, инпуты, заголовки, цветовые и типографические переменные.
Не содержат бизнес-логики и обычно отвечают только за отображение.
Являются фундаментом дизайн-системы.
2
Молекулы (Molecules)
Группы атомов, совокупно решающие небольшую задачу интерфейса.
Молекулы всё ещё не включают в себя сложную бизнес-логику.
Пример: форма логина (инпут + кнопка), карточка профиля (иконка + текст).
3
Организмы (Organisms)
Более крупные и сложные части UI, которые состоят из нескольких молекул (и/или атомов).
Могут содержать первые признаки бизнес-логики, но в целом ориентированы на UI.
Пример: панель навигации (с вложенными пунктами, формами поиска, кнопками).
4
Шаблоны (Templates)
Каркасные макеты страниц, определяющие расположение организмов, молекул и атомов.
Не содержат конкретного контента, но задают структуру.
Пример: макет главной страницы с шапкой, блоком контента и подвалом.
5
Страницы (Pages)
Конечная реализация шаблона с реальными данными и контентом.
Именно страницы видит пользователь, и здесь происходит взаимодействие.
Пример: главная страница сайта, заполненная товарами, баннерами, формами.
Преимущества Atomic Design
Чёткая организация
Каждый компонент имеет своё место в иерархии: атом, молекула, организм, шаблон или страница.
Переиспользование
Атому или молекуле достаточно один раз описать стили и поведение. Затем их можно повторно использовать в различных местах приложения.
Согласованность
Все UI-элементы объединены единым визуальным стилем и принципами. Изменение в атоме (например, цвета) автоматически применяется ко всем молекулам и организмам, где он используется.
Ускорение разработки
Благодаря готовому набору «кирпичиков» (атомов, молекул, организмов), можно быстро собирать новые страницы и шаблоны.
Недостатки Atomic Design
Подходит не для всех типов проектов
Отлично работает для дизайн-систем и UI-библиотек, но может быть избыточен для больших бизнес-приложений, где важна сложная логика и структура.
Размытая граница между уровнями
В реальных проектах порой сложно определить, что относить к молекулам, а что к организмам. Возникают споры и путаница.
Отсутствие бизнес-ориентированности
Подход, в первую очередь, решает вопросы UI; организации бизнес-логики в проекте он не затрагивает.
Когда использовать Atomic Design
Создание или развитие UI-кита
Atomic Design служит идеальным фундаментом для дизайн-системы, где важна единообразная стилистика и переиспользуемость компонентов.
Проекты с высокой частотой изменений
Если интерфейс часто перерабатывается и обновляется, методология помогает быстро вносить правки, меняя атомы и молекулы.
Командная работа
При большом числе разработчиков и дизайнеров единая архитектура UI ускоряет коммуникацию и снижает риск дублирования.
Вопрос:
Atomic Design (Атомарный дизайн)
Модульная архитектура — это подход, при котором проект разбивается на автономные блоки (модули), каждый из которых имеет четкую область ответственности и минимальные связи с другими. Это облегчает поддержку, тестирование и масштабирование приложения, а также помогает командам эффективно делить задачи.
Ключевая идея:
Модули не зависят напрямую друг от друга — они могут использовать только «ядро» (core) для взаимодействия с общими сервисами и UI-компонентами.
Любые детали реализации модуля (внутренние файлы, функции, состояния) инкапсулированы и доступны извне только через Public API.
Основные принципы
1
Независимость модулей
Изменения в одном модуле не ломают работу других модулей. Если функциональность модуля больше не нужна, достаточно удалить его папку, и система продолжит работать без этой части функционала.
2
Инкапсуляция
Всё, что относится к модулю (компоненты, стили, утилиты, логику), хранится внутри одной папки. Взаимодействовать с модулем снаружи можно только через Public API, что защищает внутреннюю реализацию от внешних зависимостей.
3
Зависимость только от «ядра» (core)
Если модулям нужны общие сервисы (например, логгер, сетевые запросы, роутинг), они берут их из ядра. Модули не должны напрямую зависеть друг от друга.
4
Однонаправленный поток
Данные идут сверху вниз: pages ⇒ modules ⇒ components ⇒ UI.
Такая структура упрощает понимание, в каком месте обрабатывается бизнес-логика.
Пример структуры
FileTree
Bash
Source Code
Core
Public API для ядра
Общие UI-компоненты
Общие сервисы
Modules
Auth Module
Public API модуля
Компоненты модуля
Утилиты модуля
User Module
Public API модуля
Компоненты модуля
Логика и типы
Pages
Главная страница
Профиль
Плюсы
Масштабируемость: добавление нового модуля или удаление старого не ломает всё приложение.
Ясные границы: чётко понятно, какой функционал за что отвечает и где его искать.
Изоляция: внутренняя реализация спрятана от других частей приложения.
Простота командной работы: каждый разработчик может вести свой модуль, не затрагивая чужие.
Минусы
Сложность разбиения: не всегда очевидно, когда выносить код в отдельный модуль, а когда оставить в компонентах.
Потенциальное дублирование: если один модуль не может напрямую использовать другой, иногда приходится копировать часть кода или выносить общий функционал в core/shared.
Неявные связи: глобальные данные (например, store) могут использоваться по-разному, что создаёт косвенные зависимости.
Итог:
Модульная архитектура хорошо подходит для средних и крупных проектов, где необходимо чёткое разделение зон ответственности и минимизация внутренних связей между функциями. При этом важно грамотно организовать ядро (core) — именно в нём хранятся общие сервисы и компоненты, доступные всем модулям.