Классическая жизнь фронтенд-приложений и их сопровождение

от автора

Проблемы больших проектов: сопровождение компонентов и фанатичность принципу DRY

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

Пример: компонент для вывода суммы двух чисел

Первое требование: сумма двух чисел в кавычках

const SumComponent = (a, b) => `"${a + b}"`;

Второе требование: добавить вывод знака в конце

const SumComponent = (a, b, tag) => `"${a + b}"-${tag}`;

Третье требование: добавить умножение

const SumComponent = (a, b, tag, isMultiple) =>    `${isMultiple ? a * b : ''}-"${a + b}"-${tag}`;

Проблема

Компонент превращается в «монстра» с кучей аргументов. Новые пропсы зависят от старых, что усложняет сопровождение. В больших проектах это становится критичным.

Выход из ситуации: простое решение (но с дублированием)

Один из подходов — создавать отдельные компоненты для каждого кейса. Это противоречит принципу DRY, но упрощает сопровождение.

// Простая сумма const SumComponent = (a, b) => `"${a + b}"`;  // Сумма с тегом const SumComponentAndTag = (a, b, tag) => `"${a + b}"-${tag}`;  // Сумма с тегом и умножением const SumComponentAndTagAndMultiple = (a, b, tag, isMultiple) =>    `${isMultiple ? a * b : ''}-"${a + b}"-${tag}`;

Проблема этого подхода

Дублирование кода. Если логика суммы изменится, придется вносить изменения во всех компонентах.

Модульный подход: композиция функций (лучшая практика функционального программирования)

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

Базовые функции

// Базовая логика суммы const sum = (a, b) => a + b;  // Добавление кавычек const withQuotes = (fn) => (a, b) => `"${fn(a, b)}"`;  // Добавление тега const withTag = (fn) => (a, b, tag) => `${fn(a, b)}-${tag}`;  // Добавление умножения const withMultiplication = (fn) => (a, b, isMultiple) =>    isMultiple ? `${a * b}-${fn(a, b)}` : fn(a, b);

Комбинирование функций

// Простая сумма с кавычками const SumComponent = withQuotes(sum);  // Сумма с кавычками и тегом const SumComponentAndTag = (a, b, tag) => withTag(withQuotes(sum))(a, b, tag);  // Сумма с кавычками, тегом и умножением const SumComponentAndTagAndMultiple = (a, b, tag, isMultiple) =>    withMultiplication(withTag(withQuotes(sum)))(a, b, isMultiple) + `-${tag}`;

Преимущества

  1. Модульность: каждая функция отвечает за одну задачу.

  2. Переиспользование: функции можно комбинировать в любом порядке.

  3. Сопровождение: изменения в базовой логике автоматически применяются ко всем комбинациям.

Практика на Vue.js

Composition API

1. Создаем композаблы (composables)

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

useSum.js — логика суммы

import { computed } from 'vue';  export function useSum(a, b) {   const sum = computed(() => a + b);   return { sum }; }

useQuotes.js — добавление кавычек

import { computed } from 'vue';  export function useQuotes(value) {   const quotedValue = computed(() => `"${value.value}"`);   return { quotedValue }; }

useTag.js — добавление тега

import { computed } from 'vue';  export function useTag(value, tag) {   const taggedValue = computed(() => `${value.value}-${tag}`);   return { taggedValue }; }

useMultiplication.js — добавление умножения

import { computed } from 'vue';  export function useMultiplication(a, b, value, isMultiple) {   const multipliedValue = computed(() =>      isMultiple.value ? `${a.value * b.value}-${value.value}` : value.value   );   return { multipliedValue }; }

2. Создаем компоненты с использованием композаблов

Базовый компонент SumComponent

<script setup> import { useSum, useQuotes } from './composables';  const props = defineProps({   a: Number,   b: Number, });  const { sum } = useSum(props.a, props.b); const { quotedValue } = useQuotes(sum); </script>  <template>   <span>{{ quotedValue }}</span> </template>

Компонент SumComponentAndTag

<script setup> import { useSum, useQuotes, useTag } from './composables';  const props = defineProps({   a: Number,   b: Number,   tag: String, });  const { sum } = useSum(props.a, props.b); const { quotedValue } = useQuotes(sum); const { taggedValue } = useTag(quotedValue, props.tag); </script>  <template>   <span>{{ taggedValue }}</span> </template>

3. Преимущества подхода

  1. Модульность: Каждая логика изолирована в отдельном композабле.

  2. Переиспользование: Композаблы можно использовать в разных компонентах.

  3. Реактивность: Все значения автоматически обновляются при изменении пропсов.

  4. Сопровождение: Легко вносить изменения, так как логика разделена на мелкие части.

  5. Тестируемость: Каждый композабл можно тестировать независимо.

4. Пример использования компонентов

<template>   <div>     <!-- Простая сумма -->     <SumComponent :a="2" :b="3" />      <!-- Сумма с тегом -->     <SumComponentAndTag :a="2" :b="3" tag="result" />    </div> </template>  <script setup> import SumComponent from './components/SumComponent.vue'; import SumComponentAndTag from './components/SumComponentAndTag.vue'; </script>

5. Итог

Использование useComposable во Vue 3 позволяет:

  • Создавать гибкие и модульные компоненты.

  • Избегать дублирования кода.

  • Упрощать сопровождение и тестирование.

  • Легко адаптироваться к изменениям требований.

Options API

Проблемы

  1. Слоты: сложно сопровождать в больших проектах.

  2. Миксины: могут вызывать конфликты и неявные зависимости.

  3. Обычные функции с замыканиями: отсутствие автоматической реактивности.

  1. Модульный подход позволяет соблюдать DRY и упрощает сопровождение.

  2. Композиция функций делает код гибким и переиспользуемым.

  3. Composition API во Vue — современный и удобный способ организации кода.

  4. Избегайте монолитных компонентов: разделяйте логику на мелкие, независимые части.

Этот подход особенно полезен в больших проектах, где важно поддерживать баланс между гибкостью и читаемостью кода.


ссылка на оригинал статьи https://habr.com/ru/articles/893370/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *