В своей книге «Чистая архитектура» дядя Боб говорит, что докладчик должен поместить полученные данные в то, что он называет «моделью представления».
Это то же самое, что и ViewModel из шаблона проектирования Model-View-ViewModel (MVVM), или это простой объект передачи данных (DTO)?
Если это не простой DTO, как это связано с View? Получает ли представление обновления от него через отношения Observer?
Я предполагаю, что это больше похоже на ViewModel от MVVM, потому что в главе 23 своей книги Роберт Мартин говорит:
Работа [докладчика] состоит в том, чтобы принимать данные из приложения и форматировать их для представления, чтобы представление могло просто переместить их на экран. Например, если приложение хочет, чтобы в поле отображалась дата, оно передает объект Presenter a Date. Затем докладчик отформатирует эти данные в соответствующую строку и поместит их в простую структуру данных, называемую моделью представления, где представление может найти ее.
Это подразумевает, что View каким-то образом связан с ViewModel, а не просто получает его в качестве аргумента функции, например (как в случае с DTO).
Другая причина, по которой я так думаю, заключается в том, что, если вы посмотрите на изображение, Presenter использует модель представления, но не представление. Принимая во внимание, что докладчик использует как выходную границу, так и выходные данные DTO.
Если это не DTO или ViewModel из MVVM, пожалуйста, уточните, что это такое.
источник
ViewModel
есть обертка дляController
,Presenter
иViewModel
в Чистой архитектуре Дяди Боба.Controller
->ICommand
иPresenter
->data-binding mechanism
.Ответы:
Нет.
Это было бы так :
Это имеет циклы. Дядя Боб тщательно избегал циклов .
Вместо этого у вас есть это:
Который, конечно, не имеет циклов. Но это заставляет задуматься о том, как представление узнает об обновлении. Мы вернемся к этому через минуту.
Процитирую Боба с предыдущей страницы:
Так что, конечно, если хотите.
Но я сильно подозреваю, что вас действительно беспокоит это :
Это милое небольшое злоупотребление UML противопоставляет направление зависимости исходного кода с направлением потока управления. Здесь можно найти ответ на ваш вопрос.
В отношениях использования:
Поток управления идет в том же направлении, что и зависимость от исходного кода.
В отношениях реализации:
Поток управления обычно идет в направлении, противоположном зависимости исходного кода.
Что означает, что вы действительно смотрите на это:
Вы должны быть в состоянии видеть, что поток управления никогда не попадет из Presenter в View.
Как это может быть? Что это означает?
Это означает, что у представления либо есть свой собственный поток (что не так уж необычно), либо (как указывает @Euphoric) поток управления входит в представление из чего-то еще, не изображенного здесь.
Если это тот же поток, то View будет знать, когда View-Model будет готова для чтения. Но если дело обстоит именно так, и представление является графическим интерфейсом, то ему будет трудно перекрашивать экран, когда пользователь перемещает его, ожидая БД.
Если у представления есть свой собственный поток, то у него есть свой собственный поток управления. Это означает, что для реализации этого Представление должно будет опрашивать View-Model, чтобы заметить изменения.
Поскольку докладчик не знает, что представление существует, а представление не знает, что докладчик существует, они вообще не могут вызывать друг друга. Они не могут швырять события друг в друга. Все, что может произойти, это то, что докладчик запишет модель представления, а представление прочитает модель представления. Всякий раз, когда это похоже на это.
Согласно этой диаграмме единственное, что разделяют View и Presenter, это знание View-Model. И это просто структура данных. Так что не ожидайте, что это будет иметь какое-либо поведение.
Это может показаться невозможным, но его можно заставить работать, даже если View-Model сложна. Одно небольшое обновленное поле - это все, что представление должно опрашивать, чтобы обнаружить изменение.
Теперь, конечно, вы можете настаивать на использовании паттерна наблюдателя или сделать что-то простое, чтобы скрыть эту проблему от вас, но, пожалуйста, поймите, что вам это не нужно.
Вот немного забавы, иллюстрирующее поток управления:
Обратите внимание, что всякий раз, когда вы видите, что поток идет против направлений, которые я определил ранее, вы видите возвращение вызова. Этот трюк не поможет нам добраться до Вью. Ну, если мы сначала не вернемся к тому, что называется контроллером. Или вы можете просто изменить дизайн, чтобы вы могли добраться до вида. Это также исправляет то, что выглядит как начало проблемы с доступом к данным и ее интерфейсом.
Единственное, чему здесь нужно научиться, это то, что Interactor Use Case может в значительной степени вызывать вещи в любом порядке, в котором он хочет, до тех пор, пока он вызывает ведущего.
источник
Я нахожу эту проблему слишком запутанной, и потребовалось бы много текста и времени, чтобы правильно объяснить проблему, так как я считаю, что вы неправильно понимаете как Чистую архитектуру Мартина, так и MVVM.
Первое, что нужно отметить, это то, что вы разместили диаграмму не полностью. Он показывает только «бизнес-логику», но в нем отсутствует какой-то «оркестратор», который фактически заставляет детали двигаться в правильном порядке.
Код оркестратора будет таким же простым, как
Мне кажется, я слышал, как Мартин говорил об этом в одном из своих выступлений о чистой архитектуре.
Еще одна вещь, на которую следует обратить внимание: замечание candied_orange о недостатке циклов неверно. Да, циклический не существует (и не должен) в архитектуре кода. Но циклы между экземплярами времени выполнения являются общими и часто приводят к упрощению проектирования.
Это случай в MVVM. В MVVM View зависит от ViewModel, а ViewModel использует события для уведомления View об его изменениях. Это означает, что при проектировании классов существует зависимость только от классов View до Model, но во время выполнения существует циклическая зависимость между экземплярами View и ViewModel. Из-за этого нет необходимости в оркестраторе, так как ViewModel предоставит View способ выяснить, когда обновлять себя. Вот почему в «уведомлениях» на этой диаграмме используется «волнистая» линия, а не прямая. Это означает, что View наблюдает за изменениями в ViewModel, а не потому, что ViewModel зависит от View.
Самая важная вещь, которую вы должны взять из Чистой архитектуры Мартина, это не сам дизайн, а то, как вы справляетесь с зависимостями. Один из критических моментов, которые он подчеркивает в своих выступлениях, заключается в том, что при наличии границы все кодовые зависимости, пересекающие эту границу, пересекают ее в одном направлении. На диаграмме эта граница представлена двойной линией. И есть много инверсий зависимостей через интерфейсы (
InputBoundary
,OutputBoundary
иDataAccessInterface
) , что фиксирует направление коды зависимости.В отличие от этого,
ViewModel
в чистой архитектуре просто DTO без логики. Это становится очевидным по<DS>
тегу. И это причина, почемуorchestrator
это необходимо, так какView
не будет знать, когда запустить его логику.Если бы я «сплющил» диаграмму в то, как она будет выглядеть во время выполнения, она будет выглядеть так:
Поэтому во время выполнения зависимости находятся в «неправильном» направлении, но это нормально.
Я рекомендую посмотреть его разговор о чистой архитектуре, чтобы лучше понять его рассуждения.
источник