Как Android-разработчику избавиться от комплекса доменной неполноценности
Комплекс доменной неполноценности — это когда веришь, что доменный слой приложения должен быть самым большим и самым важным, и винишь себя в том, что в твоём коде это не так. Это происходит, если воспринимать «Чистую архитектуру» как единственно верный способ писать код.
Привет, меня зовут Саша, я Head of mobile в компании «Метр квадратный». Под катом — почему появился этот комплекс и как с ним бороться. Сразу оговорюсь, в статье много моего личного мнения, и будет круто, если в комментах вы поделитесь своим.
Как мы до такого докатились?
Перенесёмся в 2009 год. Только‑только вышел Android 2.0.1, а Android‑разработка — занятие почти неизвестное. Телефоны совсем слабые, а приложения — простые и легковесные. У скромного комьюнити разработчиков есть столь же скромная документация, в которой рекомендуется держать весь код приложения в многочисленных Activity. Если какой‑то код вы вынесете в отдельный класс, это будет считаться верхом искусства ООП.
Но с 2009 года многое изменилось: часть разработчиков начали писать по канонам «Чистой архитектуры», приложения стали гигантскими, а бизнес‑логики в них стало пропорционально меньше. Пришлось отдать это «голодающим» бэкенд‑разработчикам.
Конечно, можно привести примеры приложений с жирным доменным слоем (и хрустящей корочкой из юнит‑тестов), но многим из нас (и мне в том числе) чаще приходилось писать совсем другие приложения. Что‑то по ТЗ типа: «Возьми вот эти данные и покажи их вот в этом списочке».
Так в чём же здесь проблема, спросите вы? Я расскажу.
Умные книжки учат нас, что приложение — это бизнес‑логика. Всё остальное: UI, сеть, база данных — это всего лишь детали реализации, мелкие библиотечки, которые должны пресмыкаться перед могучим доменным слоем. На деле UseCase иногда состоят всего из пары строчек, а Entity — вообще нет.
Да-да, те data-классы, что гуляют по вашему приложению, — это ни разу не Entity, а Input/Output Data. Все вопросы к Дядюшке Бобу, это его диаграмма
Из‑за этого получается неприлично тонкий доменный слой — стыдно показывать даже друзьям. И так повторяется из проекта в проект. Кажется, у кого угодно вырастут комплексы от такого.
Я попробую копнуть в причины этого феномена, а затем будем «лечиться» от этих комплексов.
Книжки идеализируют реальность
Знаете, что общего у книг Роберта Мартина, Кента Бека и Мартина Фаулера? Они изобилуют примерами кода, «не замусоренного» UI‑фреймворками, получением данных с бэкенда и прочими мелкими деталями реализации.
Нам показывают код таким, каким он должен быть: пронизанным духом настоящего ООП, не зависящим ни от чего, прекрасно тестируемым, лаконично решающим задачу. Читаешь и радуешься: если я буду писать так же, то смогу иметь 100%‑е покрытие тестами, код будет независим от сторонних библиотек, а значит, доменный слой будет основой всего, а presentation‑ и data‑слои — лишь плагинами к доменному. Я даже смогу просто взять и заменить UI‑слой на командную строку!
Конечно, все эти идеи подкупают, в них хочется верить. Но есть одно «но».
В реальном мире всё не так
В реальной разработке мы зажаты в тиски: дизайнер принёс макеты, а бэкенд‑разработчик — API. Часто единственное, что нужно сделать, — написать адаптер от одного к другому. Такие приложения‑адаптеры обычно зовутся тонкими клиентами, бизнес‑логики в них мало.
Получается, что мы — всего лишь прослойка (как бы грустно это ни звучало).
Так android‑разработчики зарабатывают комплекс доменной неполноценности: с одной стороны, чистая архитектура учит нас чтить доменный слой, с другой стороны, кода у нас в нём — с гулькин нос.
Тогда мы или начинаем молча страдать из‑за этого, или на цыпочках идём запихивать в доменные модули всё подряд, лишь бы объём кода вырос.
Оба эти варианта ни к чему хорошему не приведут, я рекомендую остерегаться их. Моя рекомендация — немного расслабиться и сбавить градус ортодоксальности. Как это сделать? Надеюсь, следующая секция с этим поможет.
Ответы на неудобные вопросы
Дисклеймер
Осторожно! Я уже предупреждал, но предупрежу ещё раз. Вас ждёт много вкусовщины и личного мнения (хоть оно и основано на горьком опыте). Читайте на свой страх и риск.
Что делать с юзкейсом, содержимое которого — одна строчка? Вызов репозитория, и всё. Может, в этом случае вызывать репозиторий напрямую?
Любая архитектура привносит избыточность. Эта избыточность нужна для единообразия, а единообразие нужно для того, чтобы код был очевидным. Такой код легко читать и легко поддерживать: он не преподносит сюрпризов.
Если уж вы ввязались в «Чистую архитектуру» (вас же никто не заставлял?), то юзкейсы придётся писать всегда, даже однострочные. Ну, а тесты уже на вашей совести