← Назад к вопросам

Как относишься к легаси-код?

2.0 Middle🔥 201 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Отношение к legacy-коду

Legacy-код - это неизбежная реальность любого долгоживущего проекта. Я воспринимаю это как профессиональный вызов, а не как проблему.

Позитивный взгляд на наследие

В процессе работы я понял, что за каждой строкой legacy-кода стоит:

  1. Решённые проблемы - код существует потому, что кто-то прошёл через боль
  2. Бизнес-ценность - этот код работает, генерирует доход, у него есть пользователи
  3. Контекст - при переписывании легко забыть edge case'ы, которые учитывал оригинальный автор
  4. Знания - старый код часто содержит полезные паттерны, которые новый разработчик может пропустить

Практический подход к работе с legacy

1. Не переписываю без необходимости

Вот мой чек-лист перед рефакторингом:

// Вопросы, которые я себе задаю:
// 1. Есть ли проблема с производительностью? (измеримая, не предполагаемая)
// 2. Есть ли проблемы с поддерживаемостью? (есть ли баги?)
// 3. Будет ли новый код проще для будущих разработчиков?
// 4. Какой риск введения регрессий?

// Если ответы: нет, нет, может быть, высокий -> оставляю как есть

2. Маленькие итеративные улучшения

Я применяю принцип "Boy Scout Rule" - оставляю код чище, чем нашёл, но не пытаюсь переписать всё сразу:

// Было (legacy)
function processData(d) {
  if (d && d.length > 0) {
    return d.map(x => {
      return { name: x.n, age: x.a, email: x.e };
    }).filter(x => x.age > 18);
  }
  return null;
}

// Улучшаю постепенно:
// Первый проход - переименовываю переменные
function processData(data) {
  if (data && data.length > 0) {
    return data
      .map(item => ({
        name: item.n,
        age: item.a,
        email: item.e
      }))
      .filter(item => item.age > 18);
  }
  return null;
}

// Второй проход - обработка пустого массива
function processData(data) {
  if (!Array.isArray(data) || data.length === 0) {
    return [];
  }
  
  return data
    .map(item => ({
      name: item.n,
      age: item.a,
      email: item.e
    }))
    .filter(item => item.age > 18);
}

3. Тестирование перед изменениями

Всегда сначала пишу тесты для legacy-кода (даже если их не было):

describe('processData', () => {
  it('должен вернуть пустой массив если данных нет', () => {
    expect(processData([])).toEqual([]);
    expect(processData(null)).toEqual([]);
  });
  
  it('должен фильтровать по возрасту', () => {
    const input = [
      { n: 'John', a: 25, e: 'john@example.com' },
      { n: 'Jane', a: 17, e: 'jane@example.com' }
    ];
    
    const result = processData(input);
    expect(result).toHaveLength(1);
    expect(result[0].name).toBe('John');
  });
});

// Затем рефакторю - тесты гарантируют, что я ничего не сломал

4. Документирование потребностей

При работе с legacy-кодом я стараюсь зафиксировать важные детали:

// ВСЕ ЭТИ ПРОВЕРКИ НЕОБХОДИМЫ!
// email может быть строкой, массивом или undefined
// name не может быть пустой строкой (требование бизнеса)
// После рефакторинга дважды проверь эти случаи
function validateUser(user) {
  // ...
}

module.exports = validateUser;

5. Знаю когда остановиться

Легко увлечься и переписать весь старый код. Я сфокусирован на:

// ✓ Фикс реальных багов
// ✓ Улучшение читаемости (если код запутанный)
// ✓ Добавление типов (TypeScript migration)
// ✓ Улучшение производительности (если есть проблемы)

// ✗ Переписывание ради переписывания
// ✗ Внедрение последних трендов (обычно ненужно)
// ✗ Рефакторинг без тестов

Конкретный пример из опыта

На одном проекте наследовал Angular 1 компоненты. Вместо переписывания на React:

  1. Завернул в слой обёртку - сделал их совместимыми с современным стеком
  2. Добавил новые фичи рядом - писал новый код на React, старый оставил работать
  3. Постепенно мигрировал - когда падал старый компонент, переписывал на React
  4. Каждые 2-3 месяца рефакторил - маленькие улучшения, безопасные изменения

Результат: через год 80% кода было на современном стеке, не было массивного переписывания, нулевой downtime.

Основные принципы

  1. Уважаю авторов - они делали лучшее с информацией, которая была у них
  2. Меряю дважды, режу один раз - не спешу с рефакторингом
  3. Тестирование - первое - не трогаю код без тестов
  4. Коммуникация - согласую рефакторинг с командой
  5. Инкрементально - маленькие шаги, частые проверки

Legacy-код - это не враг, это активное имущество компании. Работа с ним требует опытности, терпения и проактивного подхода. Это дает возможность расти как разработчику, учиться на ошибках других и принимать мудрые решения архитектуры.

Как относишься к легаси-код? | PrepBro