Как стать автором
Обновить

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

Уровень сложностиСредний
Время на прочтение4 мин
Количество просмотров3.2K

Проблемы больших проектов: сопровождение компонентов и фанатичность принципу 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. Избегайте монолитных компонентов: разделяйте логику на мелкие, независимые части.

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

Теги:
Хабы:
+3
Комментарии9

Публикации

Истории

Работа

Ближайшие события

4 – 5 апреля
Геймтон «DatsCity»
Онлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань
20 – 22 июня
Летняя айти-тусовка Summer Merge
Ульяновская область