Pull to refresh
10
0
Send message

А какая цель у clean? Вроде та же. Тоже сделать UI переиспользуемым.

Не совсем. Вот здесь

Independent of UI. The UI can change easily, without changing the rest of the system.

имеется в виду не сделать UI переиспользуемым, а иметь возможность выбросить UI и вместо него воткнуть другой. А о переиспользуемости выбрасываемого при этом UI и речи нет. Что возвращает меня к моему тезису: великим мира сего нет дела до UI (ровно как и до базы данных, и до всего остального, что находится на периферии луковицы слоёв), они его считают лишь мелкой деталью. Причём примеры они всегда приводят такие, что мол UI меняется, БД меняется, бэк меняется, поэтому от них и надо изолироваться. Как будто бизнес-правила не меняются :)

Рискну крамольную вещь сказать. Роберт Мартин слегка ошибся со своим средним слоем. Он должен быть верхним. И вот в такой постановке архитектуры, все работает, как часы.

С языка сняли! Я прямо загорелся вашей идеей про медиаторную архитектуру. Обязательно попробую на практике.

Это приводит к проблемам переиспользования: доменную модель мы можем переиспользовать даже между платформами, а вот вью между приложениями уже не можем, т.к. даже имеющиеся вьюшки мы должны адаптировать под протоколы более низких слоев.

Да, всё так. (не случайно даже обложка у статьи представляет доменный слой королём кодовой базы). Предполагается ведь, что доменная область важнее всех, а вот эти ваши вьюшки можно выбрасывать и заменять на новые. Причём это же не только в чистой архитектуре такой перекос в доменную важность: Hexagonal Acrhitecture была сформулирована ещё раньше, чем Clean, а по сути всё то же самое.

В реальном мире вьюшки тоже хотят защищённости, но в их защиту никто не становится. Их воспринимают как плагины, которые можно по щелчку пальцев менять. Тот же Роберт Мартин на своих выступлениях регулярно приводит пример: мол, вы должны иметь возможность выбросить свой UI-фреймворк и заменить его на CLI. А на практике, я убеждён: никогда ещё ни одному мобильному разработчику не приходилось выкидывать своё SDK и делать вместо него консольный интерфейс. Да и подменить всё равно не получится. Мне очень понравилось, как об этом сказал Мартин Фаулер: мол, чтобы инвертировать зависимости и обеспечить чёткую границу между слоями, вы конечно должны обернуть весь свой UI-фреймворк в интерфейсы и максимально притвориться, что вы от него не зависите, но всё равно вы не сможете на 100% от него изолироваться. Речь причём не об изоляции на уровне кода, а изоляции на уровне концепций. Всё равно где-то придётся подстраиваться под то, что какие-нибудь А и Б — это разные экраны, и им нужны разные данные. И мы всё-таки немного подстраиваемся под них.

Вот это всё, как мне кажется, и есть основная причина комплекса доменной неполноценности.

А насчёт адаптеров и медиаторов вы прямо супер интересную тему подняли.

Если в этих терминах говорить, то можно сказать, что есть 2 уровня адаптеров. Я представляю доменный слой скорее как чёрный ящик, у которого со всех сторон есть рычаги и розетки. К нему с одной стороны приходит UI и дёргает за рычаг. А с другой стороны, в одну из его розеток воткнута вилка от репозитория, который уже сам там себе шуршит и получает данные. Так вот, розетка — интерфейс, а вилка с проводом — адаптер. Причём адаптер первого уровня. А можно и весь доменный слой воспринимать как один большой адаптер между presentation и data, но это уже тогда будет адаптер второго уровня.

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

Это значит, что общение с сервером или БД должно зависеть от того, что ниже. А ниже у вас юз кейсы. А как делают обычно? Зависимость следующая V -> x -> M. А должно быть V -> x <- M

Да, согласен полностью. Мне кажется, тут проблема как раз в том, что зачастую когда говорят М, имеют в виду data+domain (М — это же модель, а модель сразу с доменным слоем ассоциируется). Если же воспринимать их как V ~ presentation, M ~ data, x ~ domain, становится чуть лучше. Я наверное в статье не совсем правильно выразился, и вы правы, некорректно в принципе называть MVx чисто презентационными паттернами. Я имел в виду следующее: обычно, когда говорят «У нас MVC», имеют в виду «У нас вся логика в контроллере». Когда же говорят «У нас Clean с MVC на презентационном слое», имеют в виду, что презентер уже не так нагружен, потому что есть юзкейсы (и иногда даже энтити). Возможно, так не совсем корректно говорить, да.

По идее интерфейс общения с БД и сервером (View к внешним системам) у вас должны быть зависимы от внешней системы и независимы от ваших внутренностей

А тут я или в корне не согласен, или не так вас понял. Скорее второе (слово интерфейс уж слишком многогранно), но всё же попробую ответить. Обычно интерфейс для общения с БД и сервером размещается "у нас", в доменном слое, а реализуется уже в data-слое. Это позволяет воспринимать БД, бэкенд и прочее как плагины и не зависеть от них напрямую. Если и интерфейс, и реализация взаимодействия с внешними системами находятся в data-слое, то доменный слой вынужден будет зависеть от data-слоя, а это противоречит принципу, что у нас все зависимости должны идти внутрь, а доменный слой должен находиться в центре и ни от кого не зависеть. А если доменный слой ни от кого не зависит, он ничего и не может знать о том, в каком формате там у нас приходят ответы от бэкенда. И к примеру ответственность за маппинг данных из data в domain ложится на плечи того, кто будет реализовать интерфейс репозитория, а реализовать его будет уже data-слой. И только так и можно реализовать полноценную инверсию зависимостей: domain определяет интерфейсы, но ему всё равно, кто и как будет их реализовывать.

Нет, думаю, никто не слышал :) Я его так обзываю, потому что феномен есть, а общепринятого термина нет.

Да, более того, «по умолчанию» Роберт Мартин предлагает на презентационом слое делать MVCP (осмелюсь этот паттерн так назвать), где контроллер работает в одну сторону, а презентер — в другую. Я же имел в виду скорее то, что MVx зачастую воспринимается как полноценное, оформленное решение для организации кодовой базы. По крайней мере, я неоднократно с таким сталкивался. И бывает даже, что такого допущения вполне себе хватает.

Information

Rating
Does not participate
Registered
Activity