Comments 15
Компонентный подход хорош ровно до того момента, когда появляется необходимость что- либо модифицировать либо масштабировать. Вот тогда и начинаются настоящие танцы с бубнами...
Вообще-то он придуман именно для того, чтобы было легко модифицировать и масштабировать.
А вообще, low coupling and high cohesion (суть компонентного подхода) - это и есть неявная, но главная цель SOLID принципов хорошего дизайна.
Суть компонентного подхода - разделить сложную штуку на более простые части. Это не может не работать.
А вот криво реализовать это в коде, конечно, можно. Тут с вами спорить не буду)
Это может не работать, если увлечься делением штук на простые штуки и наплодить макаронного монстра со 100500 связей между компонентами, которые никто не будет в состоянии отследить. Главное ещё, каждую компоненту не забывать в генерические интерфейсы оборачивать, а в коде продожить слой dynamic_cast-ов или их аналогов. И тогда "будет счастье ".
Не надо так делать, и тогда будет счастье)
Правильно, не надо так делать. Но компоненты этому способствуют. Поэтому лучше делать в модули.
Нет, это значит, что компонентный подход был применен неправильно. Вы ударили себе молотком по пальцу и из этого сделали вывод "Молотки - это плохо".
Конечно, неправильно. Как это обычно водится, "людьми до нас". Поэтому пришлось его выкорчёвывать и переделывать. В принципе, главная ошибка данных компонентов была в том, что авторы толком не владели С++ и решили применить классический Java подход к формированию классов и интерфейсов к ним.
Но С++ не Java, подобные вещи там не проходят бесследно. Как следствие, код, набитый С-макросами, кастами, методами-пустышками, плюс свой генератор кода и редактор компонентов (глючный, падающий). И всё это чудо работало раза в 3 медленнее безкомпонентного аналога, к тому же толком не умело в потоки.
Я к тому, что компоненты не панацея против сложности и при желании с ними можно сделать ещё хуже, чем без них. Модульный же подход решил в нашем случае все проблемы. Как по мне, модули - это следующий и более продуманный этап для борьбы со сложностью. Когда каждый модуль имеет лишь внешний интерфейс и протокол инициализации, а его внутренне представление скрыто от внешнего доступа, намного сложнее что либо сломать или "сделать не так".
Приходится ломать голову, чтобы добавить что-то новое, не сломав ничего из старого. Скорость разработки падает. Знакомая ситуация?
10+ лет в Андроид разработке. Скорость разработки не падает при добавлении любого количества фич. Дальше читать не интересно...
В этом случае ваши фичи должны совсем (абсолютно) не пересекаться, что маловероятно при их большом количестве в рамках одного продукта. Очень сомнительное утверждение.
Во многом согласен. Вообще программирование - это искусство, творя которое, надо уметь использовать различные подходящие для данного произведения инструменты. Последние годы наблюдаю все больше людей-"кодеров" пишущих по инструкции. Хит сезона SOLID. Но серебрянную пулю все никак не могут найти. Борьба с одними недостатками приводит к появлению недостатков в другом месте.
Добрый день.
Вообще я с вами согласен, я и сам к примерно такому подходу со временем пришёл. Но не увидел в вашей статье некоторых моментов и мне хотелось бы понять ваш подход к такому разбиению.
Как осуществляется получение данных с разных вью-моделей ? То есть, у вас есть одна главная, в ней, судя по иллюстрации, еще несколько вложенных, затем могут быть ещё ряды вложенностей. Всё это вероятно создаётся во фрагменте, прокидываясь через конструктор. Но вот в 3 глубине прошёл запрос на сервер, который вам надо как-то обработать во 2 по вложенности VM, а затем отобразить на экране или вовсе передать для обработки в параллельную VM. Каким образом это по вашему мнению должно происходить? Выступает ли фрагмент как слушатель и координатор всех VM, либо же вы каким-либо образом делаете подписку внутри VM на своих "вложенных" а во фрагменте только на "параллельные", либо какой-то иной способ?
У "функционального блока", который судя по картинкам представляет собой какой-то условный кусок экрана, зачастую тоже предполагается также наличие связанной VM (вполне себе может быть какой-то отдельный запрос). Но допустим вам надо переиспользовать этот блок-вьюшку где-то ещё. Куда в таком случае, по вашему мнению, стоит "привязывать" ЖЦ вью-модели? Всегда "подключать отдельно" в каждом фрагменте-экране, либо каким-либо образом привязывать к ЖЦ вьюшки, либо ещё какой-то вариант?
Спасибо за интересные вопросы.
Вы спрашиваете про реализацию компонентного подхода. Этому будет посвящена моя следующая статья, которая выйдет через пару дней.
Я не использую фрагменты и библиотеку ViewModel, поэтому не хотел бы выдумывать, как их лучше всего применить. Давайте, я попробую дать универсальные рекомендации по вашим вопросам.
Про получение данных в компонентах
По возможности я стараюсь делать компоненты независимыми друг от друга. Для задачи "загрузить данные с сервера и отобразить их на экране" это всегда получается сделать.
Предположим, что есть
Компонент А
и ему нужны какие-то данные с сервера. И естьКомпонент Б
, которому нужны те же самые данные.Можно сделать, чтоб
Компонент А
грузил данные, аКомпонент Б
как-то вытаскивал их изКомпонента А
. Но это плохое решение. Оно создает лишние зависимости между компонентами.Я предлагаю поступить по-другому. Пусть оба компонента обращаются за данными в репозиторий. Репозиторий нужно сделать достаточно умным — он должен выполнять дедупликацию запросов. Это значит, что если к нему обратиться за одними и теми же данными в течение небольшого промежутка времени, то сетевой запрос выполнится всего один раз.
Итого, компоненты, которые просто грузят и отображают данные, можно сделать независимыми.
Конечно, бывают более сложные случаи, когда компоненты взаимодействуют друг с другом. В следующей статье я расскажу про это подробнее.Про ЖЦ функциональных блоков
Если один и тот же функциональный блок нужен на нескольких экранах, то я просто создаю на нужных экранах по инстансу этого функционального блока. Как правило, время жизни функционального блока совпадает с временем жизни экрана. Но, наверное, бывают случаи, когда функциональные блоки появляются и пропадают динамически, тогда время жизни не будет совпадать.
Компонентный подход. Боремся со сложностью в Android-приложениях