ITNEWS.pro
5 июля 2023 в 11:31
Подписаться
Принципы SOLID во VUE

Все разработчики рано или поздно сталкиваются с процессами оптимизации кода, с различными миграциями и совершенствованием проекта. Молодые специалисты обычно делают это столкнувшись с проблемами своего, опытные ребята сразу применяют его на практике. В этом топике речь пойдет про принципы SOLID и то, как они применими к фреймворку Vue 3. Принципы SOLID - это набор рекомендаций по написанию сопровождаемого и масштабируемого кода. Они не ограничиваются определенными языками программирования или технологиями и могут быть применены к любому виду разработки программного обеспечения, включая разработку front-end.

Далее я подробно расскажу о каждом принципе и мы с вами рассмотрим их роль в улучшении нашей работы с Vue.

undefined

1. Принцип единой ответственности (Single Responsibility Principle)

Всегда кажется правильным написать один класс/функцию, которая возьмет на себя все бремя бизнес-логики. Проблема такого подхода заключается в том, что ваш код станет непредсказуемым, технический термин - "не поддерживаемым". Предположим, у вас есть очень сложный класс с множеством функций, и вам нужно внести небольшое изменение в одну из этих функций. Как вы сможете отследить последствия этого изменения на протяжении всего поведения класса? Именно здесь вступает в игру правило SRP. Если вы ограничите каждый класс одной ответственностью, вам больше не придется беспокоиться о последствиях необходимого изменения в этом классе, так как вам будет гораздо легче понять последствия этого изменения в вашем классе.

Рассмотрим следующий пример:

undefined

Как вы можете видеть, здесь есть три различных компонента со своей собственной ответственностью: CarList, CarFilter и CarDetail.

Компонент CarList отвечает за отображение списка машин и испускание события car-selected при выборе товара.

Компонент CarFilter отвечает за отображение списка моделей машин и выдачу события car-category-selected при выборе модели.

Компонент CarDetail отвечает за отображение подробной информации о выбранном моделе.

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

2. Принцип открытости/закрытости (Open/Closed Principle)

Этот принцип довольно прост. Самое простое объяснение, которое я могу придумать, - это объяснение в Clean Code JavaScript:

Программные объекты (классы, модули, функции и т.д.) должны быть открыты для расширения, но закрыты для модификации. Этот принцип в основном гласит, что вы должны позволить пользователям добавлять новые функциональные возможности без изменения существующего кода.

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

Вот наш компонент List.vue:

undefined

 

А вот наш компособал (useSorting.js)

undefined

И компонент App, который использует компонент list и добавляет к нему функцию сортировки с помощью композита useSorting:

undefined

Это демонстрирует принцип открытости/закрытости, поскольку поведение компонента List расширяется за счет добавления нового кода, а не модификации его исходного кода.

По сути, мы не реализуем этот принцип самостоятельно. Основанная на компонентах архитектура Vue и его реактивная система данных обеспечивают естественный способ следовать принципу Open/Closed в нашем коде.

3. Принцип замещения Лискова (Liskov Substitution Principle)

Несмотря на свое довольно страшное название, этот принцип просто утверждает, что объекты суперкласса должны быть заменяемы объектами подкласса без ущерба для корректности программы.

Вот пример того, как этот принцип может быть применен к компонентам Vue. В этом примере у нас есть компонент, который отображает форму с кнопкой отправки (Form.vue):

undefined

Вот подкласс, который расширяет базовый компонент и добавляет два текстовых поля:

undefined

В этом подклассе мы добавили два текстовых поля для ввода пользователем имени пользователя и пароля. Подкласс может быть использован вместо базового компонента без изменения общей функциональности приложения. Когда форма будет отправлена, по-прежнему будет вызываться метод submit из базового компонента, а сообщение будет записываться в консоль.

Следуя таким образом принципу замещения Лискова, разработка пользовательского интерфейса может стать более гибкой и масштабируемой, что облегчает сопровождение и расширение приложения с течением времени.

Как и принцип "Открыто/Закрыто", принцип замещения Лискова - это то, что уже интегрировано в архитектуру Vue, и мы используем его, не зная, как он на самом деле называется.

4. Принцип разделения интерфейсов (Interface Segregation Principle)

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

ISP - одна из ключевых причин использования компонентов в Vue (или любом другом компонентном фреймворке). Он дает нам возможность разбивать сложные структуры на более мелкие компоненты с более простым поведением и единичными обязанностями.

Рассмотрим следующий пример:

undefined

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

5. Принцип инверсии зависимостей (Dependency Inversion Principle)

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

Чтобы лучше понять этот принцип, я собираюсь сделать шаг назад в процесс создания веб-приложений. Веб-приложение обычно состоит из четырех частей: база данных, внутренняя часть, API и внешняя часть. Такое разделение веб-приложения на части уже является примером DIP. Например, в контексте DIP, API определяет контракт между двумя частями веб-приложения, а именно front-end и back-end. Компоненты front-end не полагаются на конкретную детализацию данных, хранящихся в базе данных, они просто связываются с сервисом back-end через предопределенные инструкции и методы API. Затем хранящиеся данные будут соответствующим образом изменены, что означает, что детали зависят от абстракций.

Теперь давайте вернемся к самому Vue. Приверженность компонентной архитектуре Vue уже является способом следования DIP. Мы создаем многократно используемые компоненты, чтобы определить, как данные будут отображаться для пользователей.

Другой пример - использование props в Vue. Мы используем их для передачи данных в компонентах. Таким образом, реквизиты сами по себе являются реализацией DIP, поскольку они действуют как контракт между двумя компонентами, чтобы изменить способ отображения данных для пользователей.

Сервисы в Vue также являются отличным примером следования DIP. Компоненты Vue используют сервисы для доступа к данным, возможно, изменяют их при получении и, наконец, отображают их пользователям.

Был рад поделиться знаниями, увидимся в следующем посту!

Подписывайся на наш Telegram и не пропусти главные новости!