Как стать автором
Обновить
m2_tech
Строим лучшую PropTech-компанию в России

Как Android-разработчику избавиться от комплекса доменной неполноценности

Время на прочтение5 мин
Количество просмотров2.7K

Комплекс доменной неполноценности — это когда веришь, что доменный слой приложения должен быть самым большим и самым важным, и винишь себя в том, что в твоём коде это не так. Это происходит, если воспринимать «Чистую архитектуру» как единственно верный способ писать код.

Привет, меня зовут Саша, я Head of mobile в компании «Метр квадратный». Под катом — почему появился этот комплекс и как с ним бороться. Сразу оговорюсь, в статье много моего личного мнения, и будет круто, если в комментах вы поделитесь своим.

Как мы до такого докатились?

Перенесёмся в 2009 год. Только‑только вышел Android 2.0.1, а Android‑разработка — занятие почти неизвестное. Телефоны совсем слабые, а приложения — простые и легковесные. У скромного комьюнити разработчиков есть столь же скромная документация, в которой рекомендуется держать весь код приложения в многочисленных Activity. Если какой‑то код вы вынесете в отдельный класс, это будет считаться верхом искусства ООП.

Но с 2009 года многое изменилось: часть разработчиков начали писать по канонам «Чистой архитектуры», приложения стали гигантскими, а бизнес‑логики в них стало пропорционально меньше. Пришлось отдать это «голодающим» бэкенд‑разработчикам.

Конечно, можно привести примеры приложений с жирным доменным слоем (и хрустящей корочкой из юнит‑тестов), но многим из нас (и мне в том числе) чаще приходилось писать совсем другие приложения. Что‑то по ТЗ типа: «Возьми вот эти данные и покажи их вот в этом списочке».

Так в чём же здесь проблема, спросите вы? Я расскажу.

Умные книжки учат нас, что приложение — это бизнес‑логика. Всё остальное: UI, сеть, база данных — это всего лишь детали реализации, мелкие библиотечки, которые должны пресмыкаться перед могучим доменным слоем. На деле UseCase иногда состоят всего из пары строчек, а Entity — вообще нет.

Да-да, те data-классы, что гуляют по вашему приложению, — это ни разу не Entity, а Input/Output Data. Все вопросы к Дядюшке Бобу, это его диаграмма
Да-да, те data-классы, что гуляют по вашему приложению, — это ни разу не Entity, а Input/Output Data. Все вопросы к Дядюшке Бобу, это его диаграмма

Из‑за этого получается неприлично тонкий доменный слой — стыдно показывать даже друзьям. И так повторяется из проекта в проект. Кажется, у кого угодно вырастут комплексы от такого.

Я попробую копнуть в причины этого феномена, а затем будем «лечиться» от этих комплексов.

Книжки идеализируют реальность

Знаете, что общего у книг Роберта Мартина, Кента Бека и Мартина Фаулера? Они изобилуют примерами кода, «не замусоренного» UI‑фреймворками, получением данных с бэкенда и прочими мелкими деталями реализации.

Нам показывают код таким, каким он должен быть: пронизанным духом настоящего ООП, не зависящим ни от чего, прекрасно тестируемым, лаконично решающим задачу. Читаешь и радуешься: если я буду писать так же, то смогу иметь 100%‑е покрытие тестами, код будет независим от сторонних библиотек, а значит, доменный слой будет основой всего, а presentation‑ и data‑слои — лишь плагинами к доменному. Я даже смогу просто взять и заменить UI‑слой на командную строку!

Конечно, все эти идеи подкупают, в них хочется верить. Но есть одно «но».

В реальном мире всё не так

В реальной разработке мы зажаты в тиски: дизайнер принёс макеты, а бэкенд‑разработчик — API. Часто единственное, что нужно сделать, — написать адаптер от одного к другому. Такие приложения‑адаптеры обычно зовутся тонкими клиентами, бизнес‑логики в них мало.

Получается, что мы — всего лишь прослойка (как бы грустно это ни звучало).

Так android‑разработчики зарабатывают комплекс доменной неполноценности: с одной стороны, чистая архитектура учит нас чтить доменный слой, с другой стороны, кода у нас в нём — с гулькин нос.

Тогда мы или начинаем молча страдать из‑за этого, или на цыпочках идём запихивать в доменные модули всё подряд, лишь бы объём кода вырос.

Оба эти варианта ни к чему хорошему не приведут, я рекомендую остерегаться их. Моя рекомендация — немного расслабиться и сбавить градус ортодоксальности. Как это сделать? Надеюсь, следующая секция с этим поможет.

Ответы на неудобные вопросы

Дисклеймер

Осторожно! Я уже предупреждал, но предупрежу ещё раз. Вас ждёт много вкусовщины и личного мнения (хоть оно и основано на горьком опыте). Читайте на свой страх и риск.

Что делать с юзкейсом, содержимое которого — одна строчка? Вызов репозитория, и всё. Может, в этом случае вызывать репозиторий напрямую?

Любая архитектура привносит избыточность. Эта избыточность нужна для единообразия, а единообразие нужно для того, чтобы код был очевидным. Такой код легко читать и легко поддерживать: он не преподносит сюрпризов.

Если уж вы ввязались в «Чистую архитектуру» (вас же никто не заставлял?), то юзкейсы придётся писать всегда, даже однострочные. Ну а тесты уже на вашей совести 😉

У меня огромная вью‑модель (презентер, контроллер, etc.) с кучей логики. Она готовит данные для отображения. Может, эту логику унести в доменный слой? Там всё равно пусто.

Хорошая попытка, но нет. В доменном слое не должно быть никаких намёков на то, как и кем будут отображаться данные. А вью‑модель можно просто разбить на части.

Ладно, а навигация? Ведь удобно же, когда юзкейс сам общается с роутером/навигатором.

Нет, нет, и ещё раз нет! Какие у вас экраны и как они сменяются — дело презентационное, и точка. Если юзкейсу суждено быть однострочным, смиритесь с этим, не надо пытаться его искусственно раздуть.

Если presentation‑ и data‑слои — мелочи и детали реализации, то какой процент останется от приложения, если их удалить, а оставить только доменный слой?

Очень небольшой. И хотя можно довольно точно описать все фичи приложения, прочитав только код доменного слоя, всё же нельзя считать слои данных и представления второстепенными. Их тоже надо холить и лелеять (и покрывать тестами, пусть там это делать и сложнее).

А что, если рассматривать Android‑приложение лишь как часть большой системы? Ведь тогда всё встаёт на свои места: доменный слой располагается где‑то на бэкенде, а наше приложение и есть презентационный слой системы.

Можно и так. Взять какую‑нибудь архитектуру из семейства MVx. То, что в «Чистой архитектуре» занимает целых два слоя, domain и data, в MVx — всего лишь буква M.

Если эта самая модель совсем маленькая, не надо размазывать её по всяким UseCase, Entity и Repository, не тратьте своё время.

Вместо заключения будем препарировать торт

Кодовая база — она как торт. Ну, согласитесь. Сложность приложения — это высота торта, и в этом измерении количество слоёв очень важно. Если торт высокий, ему нужно много слоёв, а если совсем низенький, то будет достаточно и трёх слоёв.

Комплекс доменной неполноценности — это когда ваши слои толщиной с бумагу. Но вы прекрасно знаете, что с этим делать в следующий раз: не переусложнять. В этой ситуации главное не путать высоту торта с его объёмом. Торт может быть большим по площади (много фич), но невысоким.

Со всех сторон нам говорят, что большим проектам нужна сложная архитектура. Но ведь площадь торта и его высота — это же совсем разные измерения (да‑да, площадь не измерение, но так нагляднее, чем говорить о длине и ширине).

Ориентироваться при выборе архитектуры нужно не на количество фич, а на сложность самой сложной из них (тут придётся подумать наперёд, никуда не денешься). И тогда у вас всё получится, и никаких комплексов не будет.

И в нашем случае торт — это не ложь!
И в нашем случае торт — это не ложь!

Теги:
Хабы:
+12
Комментарии12

Публикации

Информация

Сайт
m2.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Макс Дмитров