Модель в MVVM: бизнес-объект или что-то еще?

Текстовые выборы перетаскивать-отбрасывания к окну Watch, в то время как в отладчике.

9
задан serialhobbyist 9 December 2009 в 19:35
поделиться

6 ответов

Ценность, добавленная моделью, заключается в ее отделении от ViewModel и View. Подумайте, если бы вам пришлось создавать и поддерживать бизнес-логику в ViewModel, у вас было бы много дублированного кода.

Например, если у вас была автомобильная игра с GearBoxView (элемент управления в CockpitView), CarViewModel и CarModel - преимущество абстрагирования того, что находится в CarModel, от CarViewModel заключается в том, что CarModel может использоваться в WorldViewModel и любой другой ViewModel. CarModel может иметь отношения с другими моделями (GearsModel, WheelModel и т. Д.).

Ваш вопрос конкретно задан об использовании модели в качестве бизнес-объекта или для управления бизнес-объектами: мой ответ - он может делать и то, и другое - и должен отвечать за оба.

Вот пример

public class WorldModel //Is a business object (aka game object)
{
    private List<CarModel> _cars;
    public List<CarModel> Cars
    {
        get //Here's some management of other business objects
        {
            //hits NetworkIO in a multiplayer game
            if(_cars == null)
            {
              _cars = myExternalDataSource.GetCarsInMyGame();
            }
            return _cars;
        }
    }
    public Level CurrentRaceCourse { get; set; }
    public CourseTime TimeElapsed { get; set; }
}
0
ответ дан 4 December 2019 в 23:39
поделиться

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

Для меня мой бизнес объекты, которые возвращаются из моей службы WCF, я считаю своей моделью . Из-за этого мои проекты не имеют такой красивой файловой структуры со святой троицей пространств имен: * .Models, * .ViewModels и * .Views. Я лично считаю объекты, возвращаемые из бизнес-логики или чего-то подобного , «моделью» .

Некоторые люди склонны объединять бизнес-объекты и бизнес-логику вместе и называть это «моделью», но я нахожу это немного запутанным , потому что я представляю Модель более статичной, чем бизнес-логика, но это семантика .

Итак, когда вы смотрите на примеры MVVM проектирует и ничего не видит очень четко «Модель», это просто потому, что люди относятся к ним по-разному. Если приложение не является очень автономным, я бы на самом деле с большим подозрением отнесся к приложению с реальным пространством имен * .Model , если честно.

Еще одна замечательная вещь - это то, что вы уже много раз уже вложили средства в эти типы бизнес-объектов, и я думаю, что многие люди видят «MVVM» и сразу же предполагают, что им нужно начать определение «M», даже если то, что у них уже есть, прекрасно.

Путаница между a Модель и ViewModel довольно распространены, тоже. По сути я знаю, что мне нужна ViewModel, если мне нужна комбинация данных и поведения . Например, я бы не ожидал, что INotifyPropertyChanged будет реализован в модели, но я бы хотел ViewModel.

3
ответ дан 4 December 2019 в 23:39
поделиться

I think of the model as something that contains the smallest units of business entities. The entities in the model are used not only across the view models in my application but even across applications. So one model provides for many applications and, for those applications using MVVM, many view models.

The view model is an arbitrary collection of entities from the model that are brought together to serve whatever the view needs. If a view requires 2 of these and 1 of those, then its view model provisions them from the model. Generally, I have 1 view model per view.

So a model is like a grocery store. A view model is like a shopping cart. And a view is like a household.

Each household has unique requirements. And each household has its own shopping cart that cherry picks what the household needs from the grocery store.

0
ответ дан 4 December 2019 в 23:39
поделиться

Существует множество различных реализаций и интерпретаций.

Однако, на мой взгляд, ценность ViewModel проистекает из координации.

Модель представляет бизнес-данные. Он инкапсулирует скалярную информацию, а не процесс.

Представление , очевидно, является представлением модели.

Модель представления является координатором. На мой взгляд, задача модели представления - координировать вид и модель. Он НЕ должен содержать бизнес-логику, но фактически должен взаимодействовать с бизнес-сервисами.

Например, если у вас есть представление, которое представляет собой список виджетов, и виджеты взяты из службы, то я бы положил:

] Модель представляет собой список Представление - это ListBox, привязанный к свойству ViewModel Виджеты Модель ViewModel предоставляет свойство Widgets . У него также есть ссылка IWidgetService , к которой он может обращаться, чтобы получить эти виджеты.

В этом случае представление координируется с бизнес-объектом, поэтому оно не должно ничего о нем знать. . Модель должна игнорировать модели представлений, представления и все остальное ... они должны существовать независимо от того, как они используются. IWidgetService будет привязан к модели представления с использованием некоторого источника контейнера внедрения зависимостей, либо инъекции конструктора с помощью Unity, либо импорта с использованием MEF и т. Д.

Надеюсь, что это имеет смысл ... не перегружайте ваша модель просмотра. Думайте об этом как о координаторе, который понимает бизнес-объекты и модель, но не знает представления или того, как выполняется бизнес-процесс.

1
ответ дан 4 December 2019 в 23:39
поделиться

Из других ответов должно быть очевидно, что отношения между ViewModel и Model несколько нечеткие. Имейте в виду, что ничто не мешает вам иметь ViewModel и Model в одном классе, и когда ваши требования в определенной области достаточно просты, возможно, это все, что вам нужно!

Как вы структурируете разделение между ViewModel и Model, будет во многом зависит от потребностей проекта или программного обеспечения, которое требует этого, насколько требовательны ваши сроки и насколько вы заботитесь о наличии хорошо структурированной и поддерживаемой базы кода.

Разделение ViewModel и Model - это просто способ структурирования вашего кода . Есть много разных способов структурировать код, даже в рамках этого шаблона! Поэтому неудивительно, что разные программисты проповедуют разные подходы. Главное, что разделение может помочь упростить и сделать повторно используемые независимые части кода. Когда у вас есть четко разделенные бизнес-данные, бизнес-логика и логика представления, вы можете легко смешивать, сопоставлять и повторно использовать свои представления, логику и данные для создания новых пользовательских интерфейсов. Разделенный и упрощенный код также часто легче понять, протестировать, отладить и поддерживать.

Очевидно, не все согласятся с этим ответом. Я думаю, что это часть неотъемлемой нечеткости проблемы. В общем, вам нужно рассмотреть и найти компромисс между преимуществами и затратами на разделение между ViewModel и Model и знать, что не всегда легко решить, что входит в ViewModel, а что - в модель.

2
ответ дан 4 December 2019 в 23:39
поделиться

Мои мысли

("Модель" )

Есть одна модель. Просто данные без методов (кроме тех случаев, когда для платформы подходят какие-то простые методы получения / установки).

(«Модель представления»)

На мой взгляд, обоснование модели представления следующее:

(1) для обеспечения резервной копии полей с меньшими требованиями к ОЗУ, чтобы представления, скрытые за другими представлениями , могли быть выгружены и перезагружены (для экономии ОЗУ до тех пор, пока они не появятся из-за закрывающих их представлений). Очевидно, что это общая концепция, которая может быть бесполезной или бесполезной для вашего приложения.

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

Если ни одно из этих условий не применимо, использование модели представления, на мой взгляд, неуместно.

Если модели представления подходят, имейте отношение один к одному между моделями представления и представлениями.

Может быть важно отметить / напомнить / указать на то, что с множеством наборов инструментов пользовательского интерфейса, если один и тот же объект "String" упоминается дважды (как в модели, так и в модели представления), то память, используемая самим объектом String, не удваивается, а лишь немного больше (достаточно для хранения дополнительной ссылки на String).

(" View ")

Единственный код в представлении должен (обязательно) отображать / скрывать / переупорядочивать / заполнять элементы управления для начальной загрузки представления и (когда пользователь прокручивает или нажимает кнопки отображения / скрытия сведений и т. д.) отображение / скрытие частей представления и передача более значимых событий в «остальную часть» кода. Если требуется какое-либо форматирование текста, рисунок или что-то подобное, вид должен вызывать "остальные" кода для выполнения этой грязной работы.

(«Модель представления» еще раз)

Если (... факты о том, какие представления отображаются и ...), значения полей представления должны быть постоянными, т.е. выжить при выключении / перезапуске приложения, модель представления является частью модели: -: в противном случае это не так.

(«Представление» повторяется)

Представление гарантирует, что модель представления так же синхронизирована с просмотр с точки зрения изменений полей, если это необходимо, которые могут быть очень синхронизированы (при каждом изменении символа в текстовом поле) или, например, только при начальном заполнении формы или когда пользователь нажимает какую-либо кнопку «Go» или запрашивает завершение работы приложения.

(«Остальное»)

Событие запуска приложения: заполнить модель из SQL / сети / файлов / чего угодно. Если модель представления постоянна, создайте представления, прикрепленные к моделям представления, Заполните каждую модель представления из модели сразу после создания модели представления. Затем создайте представление, прикрепленное к модели представления.

(Связанный вопрос: что, если какой-либо набор данных в основном для отображения (не для редактирования) должен , а не быть полностью загружен в ОЗУ?)

Для наборов объектов, которые не должны полностью храниться в ОЗУ из-за соображений использования ОЗУ, создать абстрактный интерфейс для доступа к информации об общем количестве объектов, а также для доступа к объектам по одному.

Интерфейс и его «потребитель интерфейса» могут иметь чтобы иметь дело с количеством объектов, которые неизвестны / оцениваются и / или меняются в зависимости от источника API, предоставляющего объекты. Этот интерфейс может быть одинаковым для модели и модели представления.

(Связанная проблема: что, если какой-либо набор данных, предназначенный для редактирования, не следует полностью загружать в ОЗУ?)

Используйте настраиваемую систему подкачки через немного другой интерфейс. Поддержка измененных битов для полей и удаленных битов для объектов - они хранятся в объекте. Выгрузить неиспользуемые данные на диск. При необходимости используйте шифрование. Когда редактирование набора завершено, повторите его (загрузка страниц за раз - одна страница может содержать 100 объектов) и записать все данные или только изменения в транзакции или пакете, если это необходимо.

(Концептуальное значение MVVM?)

Чистый платформенно-независимый способ разрешить и потерять изменения данных в представлениях без повреждения модели; и разрешить передачу только проверенных данных в модель, которая остается «главной» очищенной версией данных.

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

Разделение достигается путем размещения кода, который знает обо всех трех (M / V / VM) в основной объект, отвечающий за обработку событий приложения, включая запуск и завершение работы на высоком уровне. Этот код обязательно ссылается на отдельные поля, а также на объекты. Если бы это было не так, я не думаю, что можно легко разделить другие объекты.


В ответ на ваш исходный вопрос, это вопрос степени взаимосвязи правил проверки при обновлении полей в модели.


12110] Модели плоские там, где они могут быть, но со ссылками на подмодели,

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

Но если правила более сложные:

(a) единственный метод, принимающий специальный объект, который действительно является состав обычных бизнес-объектов, содержащих данные для бесчисленных изменений полей, записывается для каждого сложного изменения модели, и метод может быть успешным или неудачным в зависимости от проверки правил - шаблон фасада;

или

(b) a " пробный прогон "/ гипотеза /" пробная "копия модели или подмножество модели создается первой, устанавливая одно свойство за раз, а затем на копии запускается процедура проверки. Если проверка прошла успешно, изменения ассимилируются в основной модели, в противном случае данные отбрасываются и возникает ошибка.

На мой взгляд, простой подход с получением / установкой предпочтительнее при анализе каждой отдельной транзакции, если только подавляющее большинство обновлений для вашей app являются сложными, и в этом случае можно использовать паттерн фасада повсюду.

Другой способ, которым модель в конечном итоге становится более сложной, чем набор полей с (возможно) простыми геттерами / сеттерами, - это если вы начинаете «улучшать» классы ' геттеры / сеттеры (с помощью инструмента сопоставления O2R) или добавление дополнительных аспектов, таких как вызовы API-интерфейсов мониторинга транзакций, API-интерфейсы безопасности (для проверки разрешений, ведения журнала и т. д.), учетных API-интерфейсов, методов, которые предварительно выбирают любые связанные данные, необходимые для получения или набор или что-то еще при получении или установке.

0
ответ дан 4 December 2019 в 23:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: