|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 257
|
|
Правильная архитектура приложения по паттерну MVVM28.08.2024, 13:55. Показов 1503. Ответов 17
Здравствуйте.
Объясните, пожалуйста, как должна выглядеть правильная архитектура приложения, из чего состоять и тд и тп. В MVVM приложение делить на 3 слоя View, Model и ViewModel . Вопрос - каждый из слоев должен быть отдельным проектом в решении или достаточно разделить на папки в одном проекте? Также Model должна ли еще делиться на уровни (на сколько я понимаю да), уровень доступа к данным DAL, уровень бизнес логики BLL. Это в свою очередь также нужно делать на несколько проектов? Как должно выглядеть решение? Проект с view, проект с VM, проект M который также разделен на несколько проектов для BLL и DAL? Также слышал про разные сервисы , которые должны например создавать нужные окна и тому подобное, что это за сервисы в каком уровне они должны храниться? Если есть ссылки на статьи или литературу, которая поможет это все понять пришлите, пожалуйста
0
|
|
| 28.08.2024, 13:55 | |
|
Ответы с готовыми решениями:
17
Правильная архитектура MVVM Правильная архитектура приложения EJB правильная архитектура приложения |
|
Модератор
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
|
|
| 29.08.2024, 16:55 | |
|
Зависит от разных факторов - тип проекта, размер, язык...
Самый простой подход - если не знаете, зачем разбивать на проекты, держите всё в одном. Обычно делят на ядро (Model) и интерфейс (View и ViewModel ). Чтобы можно было использовать ядро отдельно интерфейса. И так далее. Сначала причина - потом деление. Например, если есть код, который используется в нескольких проектах, то его стоит вынести в отдельный проект (библиотеку). Например, если если есть код Х, который использует только некоторую часть библиотеки, которую по смыслу можно выделить из библиотеки, то стоит разбить её на две. Особенно, если это позволит коду Х не тащить ненужные ему ссылки (например, на SQL Client или Web).
0
|
|
|
Модератор
|
||
| 13.10.2024, 19:10 | ||
|
MVVM, собственно, и разработан был как разновидность MV* адаптированная под WPF.Структура WPF решения Структура WPF+БД решения Структура связей в WPF Решении Потоки в асинхронном MVVM
0
|
||
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 257
|
|||
| 17.10.2024, 09:36 [ТС] | |||
|
если создавать отдельный проект например .net standart в котором будут храниться все интерфейсы необходимых приложению сервисов, и из каждого слоя ссылаться на этот проект и делать реализацию нужного сервиса. то все слои будут зависеть от этой библиотеки. разве это не будет нарушением DI? расширить - добавить интерфейс и где-то в нужном модуле реализовать да без проблем, но не получится без проблемно заменить эту библиотеку другой что подразумевается под моделью? просто набор классов , которые необходимы для отображению во view? или там должна быть какая-то логика? Что из себя представляет контекстная модель для работы с хранилищем?
0
|
|||
|
Модератор
|
||||||
| 17.10.2024, 23:02 | ||||||
|
Где в паттерне MVVM, есть хоть слово о DI? Если не говорит о самых простых задачах, то ОДНОЙ общей библиотеки на все слой никогда не будет. Будет какая-то общая библа, к ней будут библы для слоёв, в реализации слоя тоже будут библы. Даже на схеме Оконное приложение с учётом MVVM. Алгоритм конструирования для латунных чайников для каждого слоя указана своя библа. Суть этих библ только в замене сильных связей на слабые. В MVVM оговорены функции слоёв и как они связываются друг с другом. Но смысл это приобретает только в том случае, когда каждый слой можно заменить на другую реализацию, не трогая, не изменяя другие слои. Даже если это изменение требует только пересборки с новой связью. Реализовать это можно только убрав сильные связи между слоями. А для этого требубются какие-то внешние библы, которые необходимы и достаточны для выполнения требования по связям между слоями. В них находятся интерфейсы (или базовые классы) для "морд" слоёв и типы необходимые для работы этих интерфейсом (типы общего применения: DTO, реже POCO). Теже штеб double, string - это тоже типы общего применения, которые может использвоать любой слой. В самых простых сучаях, дробить эти (кастомные) интерфейсы и типы по нескольким сборкам не имеет смысла. Поэтому при реализации все эти библы могут быть объединены в одной сборке. Это не нарушение MVVM. Это допустимое упрощение реализации с учётом требований реальной, конкретной задачи. Но повторюсь. На практике такое встречается только в очень небольших задачах, приложениях. "Расширить" межуровневый интерфейс - это изменение архитектуры приложения. И такое может случиться только, если сильно неправильно была спроектирована архитектура, либо существенно изменилось ТЗ. Условно. Изменение внутри слоёв - это изменение подверсии приложения: 1.1, 1.2, 1.3 и т.д. А изменение взаимодействия между слоями это изменение версии 1.х, 2.х, 3.х и т.д. Одна версия от другой может отличаться настолько, что общее между ними будет только название. Обратите внимание, что там написано "Десктоп ПРИЛОЖЕНИЕ". А приложение имеет свою многослойную архитектуру с несколькими сборками. И три сборки View, Model и ViewModel - это просто тот минимум который обозначен на схеме, который необходим для разъяснения обсуждаемоего там вопроса. Добавлено через 4 минуты В теме Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп] прочитайте ближайшие посты до и после указанного. Там идёт обсуждение деталей, почему так, а не этак. Очень существенно вклад в разъяснения внёс Usaga.
0
|
||||||
|
Модератор
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
|
|
| 18.10.2024, 09:57 | |
|
Тут главное не путать два разных вопроса: декомпозиция кода по классам и разнесение этих классов по разным сборкам. В простых случаях всё находится в одной-двух сборках, но все "слои" при этом никуда не деваются.
0
|
|
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 257
|
|||
| 18.10.2024, 11:36 [ТС] | |||
|
и надо как-то сделать так чтобы модель была минимально связана с VM, а VM с view чтоб при необходимости можно было заменить 1 модуль совершенно другим (если я правильно понимаю суть MVVM)
0
|
|||
|
Модератор
|
|||||||||
| 18.10.2024, 12:19 | |||||||||
|
Внедрение зависимостей может быть таким:
Храниться в общей библиотеке. Но в данном случае "общая библиотека" - это не обязательно одна сборка. Если не получается по каким-то причинам, то 2.1. Если и это не выходит то уже тогда .Net 6 или 8. Платформозависимые классы лучше делать в отдельных сборках от платформонезависимых. Например, часто в WPF используется реализация команд использующая CommandManager - это "чисто" WPF класс. И такую реализацию лучше делать в отдельной сборке, предназначенной тольке для WPF.
1
|
|||||||||
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 257
|
|||
| 18.10.2024, 12:57 [ТС] | |||
|
а как должна выглядеть абстракция для UI (IView или IWindow)? что должно быть в этом интерфейс , ведь в классе окна у наc по хорошему не должно быть никакого кода. с абстракцией к VM вроде понятно, в интерфейсе указать хотя бы 1 метод или команду и свойство, который точно должен присутствовать в VM. а вот с абстракцией model также как и с VM? 1 какой-то класс , который должен реализовать интерфейс с методом, например, buildTree?
0
|
|||
|
Модератор
|
||||||
| 18.10.2024, 13:10 | ||||||
|
В коде выше используется платформонезависмая реализация команды.
Зависимость команды с CommandManager создаётся уже в рантайм:
0
|
||||||
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 257
|
|
| 18.10.2024, 14:55 [ТС] | |
|
Элд Хасп, посмотрел ваш пример, получается что для view не надо никакой абстракции делать (не нужно создавать интерфейсы)?
никак не могу вникнуть в то, что должно быть в модели. допустим, до этого я использовал для себя понятие объектная модель, то есть создавал папку ObjectModel создавал в ней нужные мне классы (например, User, MyObject, TreeObject) и вот при старте приложения нужно создать и заполнить эти классы, из базы взял данные. (работа с базой отдельный модуль) с этими данными нужно что-то сделать проверить, еще что-то - вот эта работа должна делаться в модели? или в отдельном проекте бизнес-логики? или во вью-модели? или в класс MyObject помимо свойств добавить методы по получению всех данных?
0
|
|
|
Модератор
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
|
|
| 18.10.2024, 15:03 | |
|
1
|
|
|
Модератор
|
||||||||
| 18.10.2024, 18:16 | ||||||||
|
В MVC и MVP - надо. Проект - это Source Code (Исходные коды). Проект может быть типа "Библиотека" или "Приложение". Проект компилируется в CIL-сборку. Для Библиотеки в *.dll, для приложения в *.exe. Exe-сборка может использоваться и как библиотека. Решение - это просто набор проектов. У сборок есть зависимости друг от друга. Те из них которые задаются в проектах и "жёстко" зафиксированы в скомпилированном коде называются "Сильными". Для их изменения нужна перекомпилиция проекта в новую сборку. Те зависимости которые создаются (корректнее - внедряются) в рантайм - называются "слабыми", поскольку они позволяют динамически при обращении к сборке настроить эти зависимости. И для их изменения не требуется перекомпиляции исходных кодов. В контексте MVVM мы говорим за СЛОИ. Слой - это не обязательно одна сборка. Может быть и несколько. Поэтому "Слой Библиотека" - это не обязательно "1 сборка библиотека". Это могут быть и отдельные сборки которыми пользуются не все, а только часть других сборок. Добавлено через 10 минут В MVVM, например, внедряются диалоги (через делегаты обратного вызова, события, сервисы, DI - роли это не имеет). А что там за диалогом скрыто - не должно иметь значения. Это может быт открытие Окна, а может быть получение данных "с Луны". Если для каких-то внутренних View функций - да. Правда не пойму зачем там может сервис понадобиться. Для взаимодействия между слоями - однозначно нет. То о чём вы пишите это рекомендация (а иногда и корпоративные правила) "Не использовать Code Behind". Code Behind в WPF - это любой Шарп-код в классе инициализация, которого происходит посредством XAML части. В других типах WPF шарп код используется очень мнгого. Без него невозможна реализация: конвертеров, Custom Control, Расширений разметки, навигаторов и многого другого. Добавлено через 2 минуты Добавлено через 1 час 9 минут Для упрощения часто под моделью понимают не весь слой, а только ту его часть через которую с ней взаимодействуют внешние потребители (в том числе ViewModel). Возможно ваш класс MyObject и есть этот фасад за которым будет инкапсулирована вся остальная логика.
2
|
||||||||
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 257
|
||
| 20.10.2024, 12:07 [ТС] | ||
|
сейчас стало чуть больше понятно. а что обычно в приложении по mvvm могут заменить? понятно что модуль получения данных, он может поменяться (БД, xml-файл еще что-то). Модель врятли, так это основа нашего приложения, замени модель - это уже новое приложение. а вот view могут решить поменять, например, захотят чтобы это было и wpf приложение и например web то есть надо заменить view как можно добиться легкости такой замены?
0
|
||
|
Модератор
|
||||
| 20.10.2024, 12:48 | ||||
|
В теме на которую давал ссылку, есть пример реализации: Пример реализации однооконного и мультиоконного Представления для одних и тех же Модели и ViewModel [WPF, Элд Хасп] Никаких IView, IWindow и подобных View интерфейсов и сервисов создавать и передавать в VM для этого не нужно. MV*.Другое дело что на практике, для упрощения часто допускают нарушения паттерна. В теме по ссылке выше я показал как заменить View на принципиально другой. Сегодня постарюсь дополнить ещё и UWP-View, если время будет. В другой теме я показал пример смены Репозитория: Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп] Сейчас я тоже работаю над проектом Avalonia, где три разных репозитория: XML, JSON и SQLite. И две разные модели: одна работает только на просмотр - для пользователей, вторая для админа - с редактированием и настройками. Добавлено через 13 минут Поэтому в одном решении может быть НЕСКОЛЬКО проектов-приложений. Например в Пример реализации однооконного и мультиоконного Представления для одних и тех же Модели и ViewModel [WPF, Элд Хасп] для разных GUI (одно или много оконный) созданы два разных проекта-решений. Но коды (компоновки приложения) в них динамические. Поэтому не проблема совместить их в одном решении, при старте читать какие-то настройки и запускать GUI в нужном режиме. Даже можно сделать консольное приложение, которые позволит выбирать между UWP и WPF GUI.
1
|
||||
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 257
|
||||||||
| 20.10.2024, 13:01 [ТС] | ||||||||
|
вы имете в виду вот это?
а если мне надо открыть окно не при закрытии второго, а чтобы они вместе были открыты? И еще момент, если я делаю не приложение WPF, а библиотеку классов WPF (плагин для другого приложения), то есть точкой входа в приложение, будет старт из другого приложения.
0
|
||||||||
|
Модератор
|
|||||||||||||||
| 20.10.2024, 14:15 | |||||||||||||||
|
Можно в настройках поставить галочки, или ввести разные роли для пользователей и использовать одну модель. В моём случае требуются именно разные модели, так как админ - это мой заказчик и его сотрудники могут вносить изменения. А пользователи - это его клиенты, которым в принципе не должна быть доступна функция изменений. Она может быть реализована как на уровне View, так и на уровне App. App "знает всё и про всех". Поэтому может "залезть" в любой слой и делать там что угодно. Другое дело, что это тоже должно быт в разумных рамках. В моём примере функцию создания окон было разумно разместить в App поскольку больше ничего в нём и нет, собственно говоря. В моём примере - это действие "закрытие окна авторизации". Там же в примере есть вывод окна сообщений, которое происходит без закрытия текущего окна:
Главное правильно запустить WPF часть. Пример запуска из консольного приложения есть в этом посте: Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп]
0
|
|||||||||||||||
|
Модератор
3134 / 2281 / 469
Регистрация: 26.03.2015
Сообщений: 8,878
|
||
| 20.10.2024, 15:15 | ||
|
0
|
||
| 20.10.2024, 15:15 | |
|
Помогаю со студенческими работами здесь
18
Правильная архитектура API приложения Правильная архитектура ASP.net приложения с wcf Правильная архитектура Android приложения, использующего restful api Архитектура консольного приложения по типу паттернов MVVM, MVC, MVP Некоторые вопросы по паттерну MVVM Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога
Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
|
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
|
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога
В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
|
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
|
|
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога
Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
|
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
|
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования.
Часть библиотеки BedvitCOM
Использованы. . .
|
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога
SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
|