Как определить, что у класса слишком много методов
Что проверяют
Умеете ли вы видеть проблему дизайна за цифрой, а не считать методы по линейке. Следом обычно просят показать, как бы вы разобрали разросшийся ViewModel или Activity в реальном проекте.
Как отвечать
Скажите сразу: число методов само по себе ничего не доказывает. Класс с тридцатью маленькими методами вокруг одной задачи бывает нормальным, а класс с десятью может делать четыре разные вещи. Смотреть стоит на признаки:
- несколько причин для изменения: правка авторизации и правка форматирования цен задевают один и тот же файл. Это прямое нарушение SRP;
- низкая связность: методы разбиваются на группы, каждая работает со своим набором полей и не трогает остальные. Такие группы и есть будущие отдельные классы;
- много зависимостей в конструкторе: если Hilt внедряет в
ViewModelсемь репозиториев и сервисов, класс координирует слишком многое; - тяжёлые тесты: чтобы проверить один метод, приходится мокать половину графа зависимостей;
- имя без смысла:
Manager,Helper,Utilsпритягивают всё подряд.
Цифры даст статический анализ. В detekt есть правила TooManyFunctions и LargeClass, их пороги настраиваются в detekt.yml, и нарушение видно в CI. Цикломатическая сложность помогает тут лишь косвенно: она про ветвление внутри метода, а не про их количество.
Как разбирать: логику сценариев выносить в use case доменного слоя, работу с данными в репозитории, преобразование в UI-состояние в отдельный маппер. В Kotlin часть поведения удобно отдать делегатам через by, а из Activity и Fragment убрать всё, кроме связи с жизненным циклом и отрисовки. В Compose огромный экран дробится на небольшие composable-функции со своим состоянием.
Где спотыкаются
Называют магическое число вроде «больше 20 методов плохо» и на этом останавливаются. Интервьюер ждёт критериев, а не порога.
Путают метрики: говорят, что высокая цикломатическая сложность означает много методов, хотя она измеряет число путей внутри одного метода.
Режут класс механически, по размеру или по алфавиту, и получают несколько классов, которые всё равно меняются вместе. Делить надо по причинам изменения, иначе связность только ухудшится.