Разработка мобильных приложений для платформы Android - одно из самых популярных направлений в области программирования на сегодняшний день. Google активно развивает эту систему и делает огромные шаги вперед в каждой новой версии ОС. Например, в версии Oreo появилось серьезное улучшение в архитектуре системы - Project Treble, влияющее на безопасность конечных потребителей. Но я считаю, что Google мог бы и лучше…

Chirita The Chicken by analyser

Project Treble - повторюсь, это классная архитектурная штука, придуманная инженерами Google, чего нельзя сказать про AndroidSDK - это ужасная архитектурная штука, которая заставляет страдать разработчиков приложений. О ней и пойдет сегодня речь. И основной вопрос, который мне хочется задать инженерам из Google: почему вы не измените архитектуру SDK? Ведь вы же знаете, что наследование классов - это плохо, что фрагменты уже много лет никого не устраивают своим жизненным циклом, что 26’000+ строк во View.java - это чересчур. Поддержка проектов, написанных на этом SDK страдает именно потому, что SDK написано в процедурном стиле.

Разберем на примере. Практически у каждого Android-разработчика был момент, когда он в процессе отладки попадает в View.java и не может определить проблему. Почему так происходит? Вот некоторые причины:

26’000+ строк

О чем тут говорить. Это много. Попадая в исходный код такого большого класса, конечно же, программист заблудится. Кому-нибудь понятно, зачем в классе View находится метод с названием resolveTextAlignment ? Или переменная private static final boolean DBG = false; ? Мне кажется, даже контрибьюторы этого класса боятся вносить туда изменения. Их страх оправдан, ведь вероятность непредвиденных ошибок большая в таком огромном scope этого файла.

52% комментариев

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

public int mPrivateFlags;
int mPrivateFlags2;
int mPrivateFlags3;

Мне кажется, 52% - это мало для такого большого класса. Глядя на код выше мне еще не ясно, что же может храниться в этих переменных, и их комментарий мне не помогает. Нужно больше. Если серьезно, то в таком классе запутывает все, даже комментарии.

630 строк комментарий к классу

Это важный пункт. Обычно комментарий к классу содержит описание поведения объекта этого класса, возможно, варианты использования. Факт, что тут 630 строк, говорит только о том, что это целая статья, перенасыщенная вариантами кастомизации и использования View.java - хотя бы нарушение принципа единственной ответственности.

3’700+ строк до первого конструктора

Что же там такого может быть? Описания полей, описания значений, которые могут принимать эти поля, описания колбеков, статическая инициализация, и, конечно же, куча комментариев. Почему важно то, что этот блок занимает 14% кода от всего класса? Потому что с этим так или иначе ведется работа в методах, некоторые статические поля имеют модификатор доступа public и доступны извне. Мало того, что они доступны, нас заставляют их использовать. Например, если нам нужно, чтобы ОС сама смогла заполнить день истечения срока действия платежной карты, то для этого View.java специально приберегла статическую переменную: AUTOFILL_HINT_CREDIT_CARD_EXPIRATION_DAY

Со стороны все это выглядит не как объект, а как пространство имен. Процедурное программирование - вот что нам дал Google. Как это не печально, большинство современных Android-программ не знают, что такое объектно-ориентированное программирование, они так и застряли в 70-х. Вы думаете, один View.java такой большой? Неа:

  • RecyclerView.java ~12’000
  • TextView.java ~11’000
  • ViewGroup.java ~9’000
  • Activity.java ~8’000
  • Fragment.java ~3’000
  • PopupWindow.java ~3’000

Но, даже если проблема была бы только во View.java, а все остальные вьюхи были бы написаны “нормально” (размером меньше, чем 300 строк), то нужно вспомнить, что эти все остальные наследуются от View.java, а наследование == копирование кусков кода из родительского класса в дочерние, и весь тот scope, который мы увидели в 26к строчках внезапно поместится в, казалось бы, безобидной вьюхе на 300 строк.

Самый главный вопрос: что делать?

Сделать все заново. Сделать заново фреймворк, в котором будут использованы принципы ОО программирования, в котором размер файлов не будет превышать 250 строк, в котором мы не увидим implementation inheritance, в котором scope будет соответствовать I из SOLID, в котором декларативный подход будет основным для решения задач пользовательского интерфейса, в котором сделать кастомную вьюху будет обычной задачей, а не сверхъестественной, в котором MaterialDesign не ограничит простор фантазии дизайнера. Можно долго еще рассуждать на тему: “А что можно будет сделать, если мы будем придерживаться принципа elegantobjects?”, и я почти уверен, результат будет на порядок выше существующего решения, от которого кровь из глаз.


Кстати, если вам, как и мне, не нравится класс View.java, то можете прокомментировать Issue про плохую архитектуру View.java.