3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
|
|
1 | |
Правильная архитектура приложения по паттерну MVVM28.08.2024, 13:55. Показов 895. Ответов 17
Здравствуйте.
Объясните, пожалуйста, как должна выглядеть правильная архитектура приложения, из чего состоять и тд и тп. В MVVM приложение делить на 3 слоя View, Model и ViewModel . Вопрос - каждый из слоев должен быть отдельным проектом в решении или достаточно разделить на папки в одном проекте? Также Model должна ли еще делиться на уровни (на сколько я понимаю да), уровень доступа к данным DAL, уровень бизнес логики BLL. Это в свою очередь также нужно делать на несколько проектов? Как должно выглядеть решение? Проект с view, проект с VM, проект M который также разделен на несколько проектов для BLL и DAL? Также слышал про разные сервисы , которые должны например создавать нужные окна и тому подобное, что это за сервисы в каком уровне они должны храниться? Если есть ссылки на статьи или литературу, которая поможет это все понять пришлите, пожалуйста
0
|
28.08.2024, 13:55 | |
Ответы с готовыми решениями:
17
Правильная архитектура MVVM Правильная архитектура приложения EJB правильная архитектура приложения Правильная архитектура API приложения |
Модератор
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
|
|
29.08.2024, 16:55 | 2 |
Зависит от разных факторов - тип проекта, размер, язык...
Самый простой подход - если не знаете, зачем разбивать на проекты, держите всё в одном. Обычно делят на ядро (Model) и интерфейс (View и ViewModel ). Чтобы можно было использовать ядро отдельно интерфейса. И так далее. Сначала причина - потом деление. Например, если есть код, который используется в нескольких проектах, то его стоит вынести в отдельный проект (библиотеку). Например, если если есть код Х, который использует только некоторую часть библиотеки, которую по смыслу можно выделить из библиотеки, то стоит разбить её на две. Особенно, если это позволит коду Х не тащить ненужные ему ссылки (например, на SQL Client или Web).
0
|
Модератор
|
|
13.10.2024, 19:10 | 3 |
99% реализаций MVVM - это C#+ XAML платформа.
MVVM, собственно, и разработан был как разновидность MV* адаптированная под WPF.Структура WPF решения Структура WPF+БД решения Структура связей в WPF Решении Потоки в асинхронном MVVM
0
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
|
|
17.10.2024, 09:36 [ТС] | 4 |
спасибо за ссылки. есть уточнения.
если создавать отдельный проект например .net standart в котором будут храниться все интерфейсы необходимых приложению сервисов, и из каждого слоя ссылаться на этот проект и делать реализацию нужного сервиса. то все слои будут зависеть от этой библиотеки. разве это не будет нарушением DI? расширить - добавить интерфейс и где-то в нужном модуле реализовать да без проблем, но не получится без проблемно заменить эту библиотеку другой правильно понимаю, что 1 проект это wpf в котором view, viewmodel и model и еще 2 проекта для бизнес логики и работы с бд? что подразумевается под моделью? просто набор классов , которые необходимы для отображению во view? или там должна быть какая-то логика? Что из себя представляет контекстная модель для работы с хранилищем?
0
|
Модератор
|
|
17.10.2024, 23:02 | 5 |
А при чём здесь DI ?
Где в паттерне MVVM, есть хоть слово о DI? Если не говорит о самых простых задачах, то ОДНОЙ общей библиотеки на все слой никогда не будет. Будет какая-то общая библа, к ней будут библы для слоёв, в реализации слоя тоже будут библы. Даже на схеме Оконное приложение с учётом MVVM. Алгоритм конструирования для латунных чайников для каждого слоя указана своя библа. Суть этих библ только в замене сильных связей на слабые. В MVVM оговорены функции слоёв и как они связываются друг с другом. Но смысл это приобретает только в том случае, когда каждый слой можно заменить на другую реализацию, не трогая, не изменяя другие слои. Даже если это изменение требует только пересборки с новой связью. Реализовать это можно только убрав сильные связи между слоями. А для этого требубются какие-то внешние библы, которые необходимы и достаточны для выполнения требования по связям между слоями. В них находятся интерфейсы (или базовые классы) для "морд" слоёв и типы необходимые для работы этих интерфейсом (типы общего применения: DTO, реже POCO). Теже штеб double, string - это тоже типы общего применения, которые может использвоать любой слой. В самых простых сучаях, дробить эти (кастомные) интерфейсы и типы по нескольким сборкам не имеет смысла. Поэтому при реализации все эти библы могут быть объединены в одной сборке. Это не нарушение MVVM. Это допустимое упрощение реализации с учётом требований реальной, конкретной задачи. Но повторюсь. На практике такое встречается только в очень небольших задачах, приложениях. Все межуровневые интерфейсы создаются на этапа проектирования архитектуры под определённое ТЗ. "Расширить" межуровневый интерфейс - это изменение архитектуры приложения. И такое может случиться только, если сильно неправильно была спроектирована архитектура, либо существенно изменилось ТЗ. Условно. Изменение внутри слоёв - это изменение подверсии приложения: 1.1, 1.2, 1.3 и т.д. А изменение взаимодействия между слоями это изменение версии 1.х, 2.х, 3.х и т.д. Одна версия от другой может отличаться настолько, что общее между ними будет только название. Нет. Обратите внимание, что там написано "Десктоп ПРИЛОЖЕНИЕ". А приложение имеет свою многослойную архитектуру с несколькими сборками. И три сборки View, Model и ViewModel - это просто тот минимум который обозначен на схеме, который необходим для разъяснения обсуждаемоего там вопроса. Вся логика по работе с данными, кроме её части относящейся к сохранению-восстановлению данных. Ну, допустим Entity Framework и/или ADO. Добавлено через 4 минуты В теме Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп] прочитайте ближайшие посты до и после указанного. Там идёт обсуждение деталей, почему так, а не этак. Очень существенно вклад в разъяснения внёс Usaga.
0
|
Модератор
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
|
|
18.10.2024, 09:57 | 6 |
Тут главное не путать два разных вопроса: декомпозиция кода по классам и разнесение этих классов по разным сборкам. В простых случаях всё находится в одной-двух сборках, но все "слои" при этом никуда не деваются.
0
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
|
|
18.10.2024, 11:36 [ТС] | 7 |
так тут MVVM postgres на скриншоте указано "App(приложение) все зависимости внедряются здесь" это разве не DI?
как это можно реализовать? добавить для каждого слоя свой интерфейс? если да, то где должны храниться эти интерфейсы? вероятно в отдельном проекте, но этот отдельный проект какого типа должен быть WPF, .Net Standart? у меня есть сервисы для работы с окнами, например , который должен получить на вход VM и по ней выдать нужную View, сервис для логирования и надо как-то сделать так чтобы модель была минимально связана с VM, а VM с view чтоб при необходимости можно было заменить 1 модуль совершенно другим (если я правильно понимаю суть MVVM)
0
|
Модератор
|
||||||
18.10.2024, 12:19 | 8 | |||||
DI - это один из инструментов для внедрения зависмостей (см. Пример реализации однооконного и мультиоконного Представления для одних и тех же Модели и ViewModel [WPF, Элд Хасп]) :
Внедрение зависимостей может быть таким:
Интерфейс или реже базовый класс (обычно абстрактный). Храниться в общей библиотеке. Но в данном случае "общая библиотека" - это не обязательно одна сборка. Лучше всегда стараться делать Standard 2.0 - так как это обеспечит максимальную платформонезависимость. Если не получается по каким-то причинам, то 2.1. Если и это не выходит то уже тогда .Net 6 или 8. Платформозависимые классы лучше делать в отдельных сборках от платформонезависимых. Например, часто в WPF используется реализация команд использующая CommandManager - это "чисто" WPF класс. И такую реализацию лучше делать в отдельной сборке, предназначенной тольке для WPF.
1
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
|
|
18.10.2024, 12:57 [ТС] | 9 |
что имеется в виду под сборкой, что-то я запутался. Есть же решение, в котором уже различные проекты (модули, например). или сборка это и есть проект?
если я правильно понял, то те сервисы (зависимости в виде интерфейсов), которые зависят от wpf делать в одном проекте библиотека WPF, а те что не зависят ни от чего , в библиотеке на .net standart? а как должна выглядеть абстракция для UI (IView или IWindow)? что должно быть в этом интерфейс , ведь в классе окна у наc по хорошему не должно быть никакого кода. с абстракцией к VM вроде понятно, в интерфейсе указать хотя бы 1 метод или команду и свойство, который точно должен присутствовать в VM. а вот с абстракцией model также как и с VM? 1 какой-то класс , который должен реализовать интерфейс с методом, например, buildTree?
0
|
Модератор
|
||||||
18.10.2024, 13:10 | 10 | |||||
В коде выше используется платформонезависмая реализация команды.
Зависимость команды с CommandManager создаётся уже в рантайм:
0
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
|
|
18.10.2024, 14:55 [ТС] | 11 |
Элд Хасп, посмотрел ваш пример, получается что для view не надо никакой абстракции делать (не нужно создавать интерфейсы)?
никак не могу вникнуть в то, что должно быть в модели. допустим, до этого я использовал для себя понятие объектная модель, то есть создавал папку ObjectModel создавал в ней нужные мне классы (например, User, MyObject, TreeObject) и вот при старте приложения нужно создать и заполнить эти классы, из базы взял данные. (работа с базой отдельный модуль) с этими данными нужно что-то сделать проверить, еще что-то - вот эта работа должна делаться в модели? или в отдельном проекте бизнес-логики? или во вью-модели? или в класс MyObject помимо свойств добавить методы по получению всех данных?
0
|
Модератор
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
|
|
18.10.2024, 15:03 | 12 |
1
|
Модератор
|
|
18.10.2024, 18:16 | 13 |
В MVVM - нет. View здесь верхний слой паттерна.
В MVC и MVP - надо. Основные моменты упрощённо. Проект - это Source Code (Исходные коды). Проект может быть типа "Библиотека" или "Приложение". Проект компилируется в CIL-сборку. Для Библиотеки в *.dll, для приложения в *.exe. Exe-сборка может использоваться и как библиотека. Решение - это просто набор проектов. У сборок есть зависимости друг от друга. Те из них которые задаются в проектах и "жёстко" зафиксированы в скомпилированном коде называются "Сильными". Для их изменения нужна перекомпилиция проекта в новую сборку. Те зависимости которые создаются (корректнее - внедряются) в рантайм - называются "слабыми", поскольку они позволяют динамически при обращении к сборке настроить эти зависимости. И для их изменения не требуется перекомпиляции исходных кодов. В контексте MVVM мы говорим за СЛОИ. Слой - это не обязательно одна сборка. Может быть и несколько. Поэтому "Слой Библиотека" - это не обязательно "1 сборка библиотека". Это могут быть и отдельные сборки которыми пользуются не все, а только часть других сборок. Добавлено через 10 минут Хоть это часто используется, но это "ни есть хорошо". Такие интерфейсы специфичны для MVC, MVP. И "перетекли" в MVVM. В MVVM, например, внедряются диалоги (через делегаты обратного вызова, события, сервисы, DI - роли это не имеет). А что там за диалогом скрыто - не должно иметь значения. Это может быт открытие Окна, а может быть получение данных "с Луны". Какой сервис? Если для каких-то внутренних View функций - да. Правда не пойму зачем там может сервис понадобиться. Для взаимодействия между слоями - однозначно нет. MVVM не определяет правила реализации внутри слоёв. То о чём вы пишите это рекомендация (а иногда и корпоративные правила) "Не использовать Code Behind". Code Behind в WPF - это любой Шарп-код в классе инициализация, которого происходит посредством XAML части. В других типах WPF шарп код используется очень мнгого. Без него невозможна реализация: конвертеров, Custom Control, Расширений разметки, навигаторов и многого другого. Добавлено через 2 минуты Все свойства к которым будет осуществлять привязка должны быть определены в интерфейсе VM. Не только свойства - все члены которые будут использоваться в View. Но в связи со спецификой платформы, кроме свойств VM в WPF редко что используется. Добавлено через 1 час 9 минут Модель в концепции MVVM это слой со всей Бизнес Логикой. В том числе к нему относятся: нужные мне классы (например, User, MyObject, TreeObject), работа с базой отдельный модуль, с этими данными нужно что-то сделать проверить и т.д. Для упрощения часто под моделью понимают не весь слой, а только ту его часть через которую с ней взаимодействуют внешние потребители (в том числе ViewModel). Возможно ваш класс MyObject и есть этот фасад за которым будет инкапсулирована вся остальная логика.
2
|
3 / 3 / 0
Регистрация: 23.12.2016
Сообщений: 140
|
|
20.10.2024, 12:07 [ТС] | 14 |
например, выбор нужного окна по переданной в него vm. ведь vm не должна ничего знать про окна, а когда вызываешь 1 окно из другого, вызов происходит из vm.
сейчас стало чуть больше понятно. а что обычно в приложении по mvvm могут заменить? понятно что модуль получения данных, он может поменяться (БД, xml-файл еще что-то). Модель врятли, так это основа нашего приложения, замени модель - это уже новое приложение. а вот view могут решить поменять, например, захотят чтобы это было и wpf приложение и например web то есть надо заменить view как можно добиться легкости такой замены?
0
|
Модератор
|
|
20.10.2024, 12:48 | 15 |
Это функция View.
В теме на которую давал ссылку, есть пример реализации: Пример реализации однооконного и мультиоконного Представления для одних и тех же Модели и 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
Сообщений: 140
|
||||||
20.10.2024, 13:01 [ТС] | 16 | |||||
либо я слишком не внимательный, либо не смог понять.
вы имете в виду вот это?
а если мне надо открыть окно не при закрытии второго, а чтобы они вместе были открыты? И еще момент, если я делаю не приложение WPF, а библиотеку классов WPF (плагин для другого приложения), то есть точкой входа в приложение, будет старт из другого приложения. тоже сейчас хочу сделать 2 режима работы, для админа и просто пользователя. как это можно реализовать, обязательно ли 2 модели если объекты будут одинаковые , только возможности разные? и view будут разные
0
|
Модератор
|
|||||||||||
20.10.2024, 14:15 | 17 | ||||||||||
Зависит от требований безопасности.
Можно в настройках поставить галочки, или ввести разные роли для пользователей и использовать одну модель. В моём случае требуются именно разные модели, так как админ - это мой заказчик и его сотрудники могут вносить изменения. А пользователи - это его клиенты, которым в принципе не должна быть доступна функция изменений. Это одна из возможных реализаций. Она может быть реализована как на уровне View, так и на уровне App. App "знает всё и про всех". Поэтому может "залезть" в любой слой и делать там что угодно. Другое дело, что это тоже должно быт в разумных рамках. В моём примере функцию создания окон было разумно разместить в App поскольку больше ничего в нём и нет, собственно говоря. Но есть же какое-то действие, событие по которому нужно открыть другое окно. В моём примере - это действие "закрытие окна авторизации". Там же в примере есть вывод окна сообщений, которое происходит без закрытия текущего окна:
Роли это не играет. Главное правильно запустить WPF часть. Пример запуска из консольного приложения есть в этом посте: Пример создания приложения "Работа с комнатами в студенческих общежитиях" [WPF, SQLite, Элд Хасп]
0
|
Модератор
3077 / 2226 / 462
Регистрация: 26.03.2015
Сообщений: 8,626
|
|
20.10.2024, 15:15 | 18 |
Лучше 2 разных приложения, использующих одну и ту же Модель (Бизнес Логику). И, возможно, Вы захотите сделать для них разные методы авторизации.
0
|
20.10.2024, 15:15 | |
20.10.2024, 15:15 | |
Помогаю со студенческими работами здесь
18
Правильная архитектура ASP.net приложения с wcf Правильная архитектура Android приложения, использующего restful api Архитектура консольного приложения по типу паттернов MVVM, MVC, MVP Некоторые вопросы по паттерну MVVM Создание диалоговых окон, согласно паттерну MVVM В указанном dsn архитектура драйвера и архитектура приложения не соответствуют друг другу Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |