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

Был ли случай когда не получалось донести до остальных свои идеи

1.2 Junior🔥 181 комментариев
#Другое#Опыт и софт-скиллы

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

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

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

Мой опыт с коммуникационными вызовами

Да, был такой случай, и я считаю его ценным уроком. Произошло это около 5 лет назад, когда я работал над миграцией приложения с MVP на Clean Architecture + MVI. Я был уверен, что этот переход решит несколько наболевших проблем:

  • Сильную связанность компонентов
  • Трудности в тестировании бизнес-логики
  • Непредсказуемое состояние UI при асинхронных операциях

Проблема и её контекст

Команда состояла из 6 разработчиков разного уровня: двое опытных, трое middle и один junior. Все привыкли к MVP, где каждый Presenter был условно «хозяином» своего экрана. Идея внедрить единый поток данных (unidirectional data flow) и вынести состояние в иммутабельные модели многим показалась избыточной.

Основные возражения были такими:

«Зачем усложнять? MVP и так работает» «Мы и так успеваем выпускать фичи» «Это замедлит разработку, нужно учить новый подход»

Мои неудачные попытки донести идею

Сначала я действовал как технократ:

  1. Устроил длинный доклад на 40 минут с диаграммами из статей Мартина Фаулера.
  2. Привёл теоретические аргументы про тестируемость и предсказуемость.
  3. Показал код из open-source проектов, который был слишком абстрактным для наших задач.
// Пример, который я показывал (упрощённо)
data class ViewState(val data: List<Item>, val isLoading: Boolean)

sealed class Intent {
    data object LoadData : Intent()
    data class ItemClicked(val id: String) : Intent()
}

class FeatureReducer {
    fun reduce(state: ViewState, intent: Intent): ViewState {
        return when (intent) {
            is Intent.LoadData -> state.copy(isLoading = true)
            // ... остальная логика
        }
    }
}

Реакция была: «Выглядит сложно. Зачем нам всё это?»

Переломный момент: смена стратегии

Я осознал, что говорю на языке абстрактных преимуществ, а команда думает о конкретных рисках и затратах. Тогда я:

  1. Выбрал самый болезненный кейс из нашего проекта — экран с фильтрами и поиском, где баги воспроизводились случайно.
  2. Создал прототип этого экрана на MVI рядом со старым MVP-кодом.
  3. Сфокусировался на конкретных выгодах:
// Старый MVP-подход (проблемная область)
class OldPresenter {
    fun onFilterChanged(filter: Filter) {
        // 1. Меняем состояние
        // 2. Отправляем запрос
        // 3. Обновляем UI частично
        // 4. Если пользователь быстро меняет фильтры — гонка условий, баги
    }
}

// Новый MVI-s подход
fun newReducer(state: State, intent: Intent): State {
    return when (intent) {
        is FilterChanged -> {
            // Все изменения централизованы, состояние иммутабельно
            // Невозможно частичное обновление, приводящее к противоречию
            state.copy(filter = intent.filter, loading = true)
        }
    }
}

Тактика «показать, а не рассказать»

  • Устроил живую демонстрацию багов в старом коде и их отсутствия в новом.
  • Написал тесты для обоих подходов, показав, что в MVI покрыть логику на 100% проще.
  • Предложил пилот на одном некритичном экране, а не на всём приложении сразу.
  • Создал чек-лист миграции с конкретными шагами и оценкой времени.

Итог и уроки

Через 2 недели пилота команда сама увидела преимущества:

  • Дебаггинг стал предсказуемым — состояние всегда можно было логировать и воспроизвести.
  • Тесты писались быстрее.
  • Новые разработчики входили в проект легче — архитектура давала чёткие правила.

Главные выводы для меня:

  1. Технические аргументы работают только на почве конкретных проблем. Без боли текущего решения преимущества нового неочевидны.
  2. Демонстрация важнее теории. Рабочий прототип убеждает лучше 100 диаграмм.
  3. Постепенное внедрение снижает сопротивление. «Большой взрыв» пугает, пилот на малой области — нет.
  4. Язык общения должен быть общим. Говорить не о «бинарных состояниях», а о «стабильности экрана фильтров».
  5. Важно слушать возражения — они часто указывают на реальные риски, которые нужно адресовать, а не отметать.

Теперь, предлагая архитектурные изменения, я начинаю с боли команды, а не с красоты решения. Сначала показываю проблему в существующем коде, затем — как новое подход её решает, и только потом обсуждаю абстрактные принципы. Это работает значительно лучше.