Чиста архітектура: що таке модель перегляду?


13

У своїй книзі "Чиста архітектура" дядько Боб говорить, що ведучий повинен вносити отримані дані в те, що він називає "Переглянути модель".

введіть тут опис зображення

Це те саме, що і 'ViewModel' з моделі дизайну Model-View-ViewModel (MVVM) або це простий об'єкт передачі даних (DTO)?

Якщо це не простий DTO, як він відноситься до Погляду? Чи отримує подання оновлення від нього через зв’язок спостерігача?

Я здогадуюсь, що це більше схоже на ViewModel з MVVM, тому що в розділі 23 своєї книги Роберт Мартін говорить:

Завданням [Ведучого] є прийняття даних із програми та форматування їх для презентації, щоб Перегляд міг просто перемістити їх на екран. Наприклад, якщо програма хоче дати в полі відображати дату, вона передасть презентатору об'єкт Date. Потім Презентатор відформатує ці дані у відповідний рядок і розмістить їх у простій структурі даних, що називається Модель перегляду, де Перегляд може їх знайти.

Це означає, що View якимось чином пов'язаний з ViewModel, на відміну від простого отримання його як функціонального аргументу, наприклад (як це було у випадку з DTO).

Ще одна причина, чому я думаю, що це тому, що якщо ви дивитесь на зображення, презентатор використовує модель перегляду, але не Вид. В той час, як презентатор використовує як вихідні межі, так і вихідні дані DTO.

Якщо він не є ні DTO, ні ViewModel від MVVM, уточнюйте, що це таке.


Я думаю, що відповідь "це залежить". Якщо це веб-додаток, то модель перегляду в основному є DTO, оскільки в кінцевому підсумку серіалізується як HTML-рядок. В іншому випадку модель перегляду - це лише спеціалізований об'єкт для відображення даних на вид.
Грег Бургхардт

У MVVM (WPF, WinForms додатків) ViewModelє оболонкою для Controller, Presenterі ViewModelв чистій архітектурі дядька Боба.
Фабіо

@Greg Burghardt - Коли ViewModel є спеціалізованою структурою даних, як View повідомляє про зміни?
Fearnbuster

@Fabio - Якщо я правильно сприймаю ваше значення, що ви говорите, що у шаблоні MVVM ViewModel еквівалентний всім компонентам, що знаходяться в самій лівій групі діаграми? Якщо це стосується архітектури дядька Боба, то чому він перераховує контролер та презентатор окремо?
Fearnbuster

Я думаю, що він розділив вхідні та вихідні обробники для різних об'єктів / класів. У MVVM це може бути Controller-> ICommandі Presenter-> data-binding mechanism.
Фабіо

Відповіді:


17

Це те саме, що і 'ViewModel' від моделі дизайну Model-View-ViewModel (MVVM)

Ні.

Це було б таке :

введіть тут опис зображення

Це цикли. Дядько Боб ретельно уникав циклів .

Натомість у вас є це:

введіть тут опис зображення

Що, звичайно, не має циклів. Але, залишаючи вас, цікаво, як погляд знає про оновлення. Ми дійдемо до цього через мить.

чи це простий об’єкт передачі даних (DTO)?

Щоб цитувати Боба з попередньої сторінки:

Якщо ви хочете, ви можете використовувати основні структури або прості об’єкти передачі даних. Або ви можете упакувати його в хешмап або сконструювати в об'єкт.

Чиста архітектура p207

Тож обов’язково, якщо вам подобається.

Але я сильно підозрюю , що насправді пристане є це :

введіть тут опис зображення

Ця мила маленька зловживання UML протиставляє напрямок залежності вихідного коду з напрямком потоку управління. Тут можна знайти відповідь на ваше запитання.

У використанні відносин:

введіть тут опис зображення введіть тут опис зображення

Потік управління йде в тому ж напрямку, що і залежність вихідного коду.

У взаємовідносинах щодо реалізації:

введіть тут опис зображення введіть тут опис зображення

потік управління, як правило, йде у зворотному напрямку, залежно від вихідного коду.

Що означає, що ви справді дивитесь на це:

введіть тут опис зображення

Ви повинні бачити, що потік управління ніколи не дістанеться від Ведучого до Погляду.

Як це може бути? Що це означає?

Це означає, що вигляд має власну нитку (що не так незвично), або (як зазначає @Euphoric) потік управління надходить у вигляд із чогось іншого, що не зображено тут.

Якщо це той самий потік, то View буде знати, коли модель View буде готова до читання. Але якщо це так, і вигляд є графічним інтерфейсом, тоді йому буде важко перефарбувати екран, коли користувач переміщатиме його, поки він чекатиме БД.

Якщо вигляд має власну нитку, то у нього є власний потік управління. Це означає, що для здійснення цього Перегляду доведеться опитувати модель View, щоб помітити зміни.

Оскільки ведучий не знає, що View існує, а View не знає, що презентатор існує, вони взагалі не можуть дзвонити один одному. Вони не можуть кидати події один на одного. Все, що може статися, це те, що ведучий напише до View-Model, а View прочитає View-Model. Кожного разу, коли це відчуває.

Згідно з цією діаграмою, єдине, на що поділяють View і Presenter, - це знання View-Model. І це просто структура даних. Тому не сподівайтеся, що вона матиме будь-яку поведінку.

Це може здатися неможливим, але його можна змусити працювати, навіть якщо View-Model є складним. Одне невелике оновлене поле - це все, що перегляд повинен опитати, щоб виявити зміни.

Тепер, звичайно, ви можете наполягати на використанні шаблону спостерігачів, або хочете, щоб це питання приховували від вас, але, будь ласка, розумійте, що вам цього не потрібно.

Ось трохи задоволення я проілюстрував потік управління:

введіть тут опис зображення

Зауважте, що коли ви бачите, як потік йде всупереч визначеним раніше напрямкам, те, що ви бачите, - це дзвінок, який повертається. Цей трюк не допоможе нам дістатися до Перегляду. Ну, якщо ми спочатку не повернемося до того, що називається Контролером. Або ви могли просто змінити дизайн, щоб ви могли перейти до перегляду. Це також виправляє те, що схоже на початок йо-йо проблеми з доступом до даних та її інтерфейсом.

Єдине інше, що тут слід навчитися, окрім цього, - це те, що інтерактор Use Case може в значній мірі називати речі в будь-якому порядку, до якого він хоче, доки він останній закликає ведучого.


Дуже дякую за відповідь, я бачив ваші відповіді на різні запитання про чисту архітектуру. Чи пропонуєте ви, що Перегляд постійно перевіряє прапор, наприклад, у моделі перегляду, щоб побачити, чи були якісь зміни? Чи повинен тоді представлення знову відображати всю модель перегляду, або я повинен використовувати набір вкладених прапорів, щоб вказати, які дані були змінені?
Fearnbuster

Перегляд не повинен постійно опитуватися. Наприклад, Web 1.0 опитується лише тоді, коли користувач натискає перезавантажити. Постійне опитування - це проектне рішення, яке повинно враховувати реальні потреби користувачів. Я просто кажу, що це можливо. Суть поля оновлення полягає у швидкому виявленні оновлення. Потрібно лише, якщо модель перегляду є складною. Також врахуйте, що станеться, якщо подання читається, поки ведучий знаходиться на півдорозі оновлення.
candied_orange

Гаразд, велике спасибі за допомогу. Якщо / коли ви дотримуєтесь цієї архітектури, це метод, який ви зазвичай використовуєте?
Fearnbuster

1
Я думаю, що є великою помилкою, що ця група відповідей разом розробляє залежність та залежність від часу виконання. Два можуть бути різними.
Ейфорія

1
@Euphoric За що дякую. Я пов'язую їх разом, тому що якщо у вас немає залежності від вихідного коду від чогось, ви не можете використовувати посилання на виконання ні для чого, оскільки ви не розумієте, що це таке. Все, що ви могли б зробити, це зберегти посилання, як це робить колекція. Якщо це помилка, я хотів би це зрозуміти.
candied_orange

2

Я вважаю цю проблему занадто заплутаною, і для того, щоб правильно пояснити проблему, знадобиться багато тексту та часу, оскільки я вважаю, що ви неправильно розумієте і чисту архітектуру Мартіна, і MVVM.

Перше, що слід зазначити, це те, що розміщена вами діаграма неповна. Він показує лише "ділову логіку", але не вистачає якогось "оркестратора", який насправді змушує деталі рухатися в потрібному порядку. введіть тут опис зображення

Код оркестратора був би таким же простим, як

string Request(string request) // returns response
{
    Controller.Run(data);
    Presenter.Run();
    return View.Run();
}

Я вірю, що я чув про це, як Мартин говорив про це в одному зі своїх розмов про «Чисту архітектуру».

Ще одна річ, яку слід зазначити, це те, що зауваження candied_orange про відсутність циклів є неправильним. Так, циклічні не існують (і не повинні) в архітектурі коду. Але цикли між екземплярами виконання є загальними і часто призводять до спрощення дизайну.

Так є в MVVM. У MVVM View залежить від ViewModel, і ViewModel використовує події для сповіщення View про зміни. Це означає, що в дизайні класів існує лише залежність від класів View до Model, але під час виконання існують циклічна залежність між екземплярами View і ViewModel. Через це немає необхідності в оркестрові, оскільки ViewModel надасть спосіб перегляду зрозуміти, коли саме оновити. Ось чому "сповіщення" на цій діаграмі використовують "чітко" лінію, а не пряму лінію. Це означає, що View спостерігає зміни в ViewModel, а не те, що ViewModel залежить від View.

введіть тут опис зображення

Найголовніше, що вам слід взяти з чистої архітектури Мартіна, - це не сам дизайн, а те, як ви справляєтесь із залежностями. Один з найважливіших моментів, який він робить у своїх переговорах, - це те, що коли існує межа, то всі кодові залежності, що перетинають цю межу, перетинають її в одному напрямку. На діаграмі ця межа представлена ​​подвійною лінією. І є багато інверсій залежностей через інтерфейси ( InputBoundary, OutputBoundaryі DataAccessInterface) , що фіксує напрямок коди залежності.

На відміну від них, ViewModelв «Чистій архітектурі» - це просто звичайний DTO без логіки. Це стає очевидним за <DS>тегом. І це є причиною, чому orchestratorце необхідно, оскільки Viewне буде знати, коли запускати це логіка.

Якби я "розрівняв" діаграму так, як вона буде виглядати під час виконання, вона виглядатиме так:

введіть тут опис зображення

Тож під час виконання залежності залежать у "неправильному" напрямку, але це нормально.

Рекомендую переглянути його розмови про чисту архітектуру, щоб краще зрозуміти його міркування.


Ваш "Оркестратор" не повинен дзвонити ведучому. Інтерактор Use Case робить це.
candied_orange

@candied_orange Щоправда, це помилка.
Ейфорія

Дякую за відповідь, завжди добре отримати кілька різних думок. Я підтримав відповіді обох ваших хлопців. Чи хтось із вас знає, чи Роберт Мартін має кодову базу десь, де він реалізував форму своєї архітектури? Я переглянув його проект FitNess, але я не побачив лісу для дерев. Також я правдивий, що навіть якщо зображення, яке я розмістив, є діаграмою, яку дядько Боб завжди використовує у своїх розмовах, це насправді лише приклад того, як може виглядати ваша архітектура? Тоді як це може виглядати дуже по-різному, якщо потік залежності правильний?
Fearnbuster

@Fearnbuster На ваше останнє запитання так. Напрямок залежностей важливіший за структуру. Я вважаю, що «Чиста архітектура», «Лукова архітектура» та «Гексагональна архітектура» - це реальні втілення однієї ідеї «Підтримувати залежність під контролем».
Ейфорія

@Euphoric Чесно кажучи, я б сказав, що це, мабуть, так, тому що в іншому образі його книги (мал. 8.2 глави 8) він показує архітектуру, яка виглядає інакше. На цій схемі контролер насправді є людиною середнього рівня між Інтерактором та Ведучим. Також немає межі виходу для інтерактора; здається, що Інтерактор отримує запити через інтерфейс, а потім повертає відповіді через той же інтерфейс (я припускаю, що це робиться через просту функцію повернення значення, оскільки я не можу придумати жоден інший механізм, який би працював таким чином).
Fearnbuster
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.