Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
1

Разбираюсь с паттерном MVP

04.07.2023, 11:10. Показов 2550. Ответов 48
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени, всем!


MVP

Правильно ли я уловил суть?


Model

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
namespace Test.Core
{
    public class DataBase
    {
        // описал "шаблон" для делегата
        public delegate void DataBaseChangedDelegate(string message);
 
        // описал событие
        public event DataBaseChangedDelegate? DataBaseChanged;
 
        // описал базу данных
        public List<string[]> dataBase = new ();
 
        // метод добавления в базу данных
        public void Add(string[] str)
        {
            // добавление в коллекцию
            dataBase.Add(str);
            
            // передаю в событие сообщение
            if (DataBaseChanged is not null)
                DataBaseChanged ("Операция добавления в базу данных...");
        }
 
        // метод удаления из базы данных
        public void Remove(string[] str)
        {
            // удаление из коллекции
            dataBase.Remove(str);
            
            // передаю в событие сообщение
            if (DataBaseChanged is not null)
                DataBaseChanged ("Операция удаления из базы данных...");
        }
    }
}

View

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
namespace Test.Core
{
    public class Viewer
    {
        public void Message(string message) => Console.WriteLine(message);
    }
}

Presenter

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
namespace Test.Core
{
    class Program
    {
        static void Main()
        {
            DataBase dataBase = new ();
 
            dataBase.DataBaseChanged += DataBaseChanged;
 
            dataBase.Add(new string[4]);
 
            dataBase.Remove(new string[4]);
        }
 
        static void DataBaseChanged(string str)
        {
            Viewer viewer= new ();
 
            viewer.Message(str);
 
            viewer.Message("База данных изменена!");
        }
    }
}


Что лучше использовать в моём случае для Model, View - Класс, Абстрактный класс, Интэрфейс или др.?

Спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.07.2023, 11:10
Ответы с готовыми решениями:

Как рисовать на форме? Пользуюсь MVP паттерном
День добрый! У меня или навык гугленья сломался или что-то еще, поэтому прошу помощи реальных...

Разобраться с паттерном Decorator
Добрый день. У кого есть время и терпенье, помогите разобрать с декоратором… (На примере С#) Хочу...

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

Не могу разобраться с паттерном Стратегия
Здравствуйте. Изучал раньше Java, сейчас хотел попробывать себя в шарпе. Но столкнулся с одной...

Незадача с паттерном Цепочка обязанностей
В общем задание такое. Реализовать сказку(колобок). Естественно не через cout . И с обязательным...

48
Эксперт по электронике
2889 / 1936 / 527
Регистрация: 04.09.2018
Сообщений: 6,607
Записей в блоге: 4
04.07.2023, 22:26 2
Цитата Сообщение от zaka4kin Посмотреть сообщение
Правильно ли я уловил суть?
Ну.. почти. Можно сказать что уловил. Однако в презентере не нужно каждый раз создавать новый View (в пределах одного приложения).

Добавлено через 2 минуты
Цитата Сообщение от zaka4kin Посмотреть сообщение
Класс, Абстрактный класс, Интэрфейс или др.?
Классы сойдут.
Абстрактный класс - в твоем случае не очень подходит.
Интерфейс можно применить, в качестве контракта для презентера... Но тоже не особо нужен в данном случае.
0
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
05.07.2023, 04:14  [ТС] 3
wizard41, понятно. изменил Presenter

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
namespace Test.Core
{
    class Program
    {
        static readonly DataBase dataBase = new ();
 
        static readonly Viewer viewer= new ();
 
        static void Main()
        {
            dataBase.DataBaseChanged += DataBaseChanged;
 
            dataBase.Add(new string[4]);
 
            dataBase.Remove(new string[4]);
        }
 
        static void DataBaseChanged(string str)
        {
            viewer.Message(str);
 
            viewer.Message("База данных изменена!");
        }
    }
}

Спасибо!
0
1978 / 1411 / 366
Регистрация: 26.06.2017
Сообщений: 4,016
05.07.2023, 17:57 4
Цитата Сообщение от zaka4kin Посмотреть сообщение
class DataBase
Нууу, скорее это не модель данных, это ближе к репозиторию. Вы же в базе собираетесь хранить вполне конкретные сущности, вот они-то и должны быть моделированы.
0
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
05.07.2023, 18:45  [ТС] 5
Цитата Сообщение от Uswer Посмотреть сообщение
Вы же в базе собираетесь хранить вполне конкретные сущности, вот они-то и должны быть моделированы.
что имеете в виду под "сущности... должны быть моделированы"?
в "базе" (List<>) будут лежать массивы строк.
не совсем понял куда клоните...
Спасибо!
0
Модератор
Эксперт .NET
15470 / 10714 / 2788
Регистрация: 21.04.2018
Сообщений: 31,544
Записей в блоге: 2
05.07.2023, 21:08 6
Цитата Сообщение от Uswer Посмотреть сообщение
Нууу, скорее это не модель данных, это ближе к репозиторию. Вы же в базе собираетесь хранить вполне конкретные сущности, вот они-то и должны быть моделированы.
Не путайте устаревший термин "Модель" из старого ADO, с термином "Модель" из семейства паттернов MV*.

"Модель ADO" - служит для парсинга SQL запросов. Даже в ЕF подобные типы называются уже "Сущность".

"Модель в паттерне" - это СЛОЙ приложения в котором находится вся Бизнес (Доменная) Логика. Состоять Модель может из очень многих других объектов. Часто Модель разбивается ещё на подслои. Одним из таких подслоёв нижнего уровня может быть Репозиторий. В задачах где кроме "общения" с БД нет другой БЛ, по сути вся Модель состоит из одного только Репозитория.

В упрощённом общении часто под Моделью понимают не весь слой, а только "морду", интерфейс этого слоя через который с Моделью "общаются" её потребители.

Добавлено через 12 минут
Цитата Сообщение от zaka4kin Посмотреть сообщение
// описал "шаблон" для делегата
        public delegate void DataBaseChangedDelegate(string message);
Вложенные публичные типы "не есть хорошо". Вынесите объявление делегата в пространство имён.

Цитата Сообщение от zaka4kin Посмотреть сообщение
// описал базу данных
        public List<string[]> dataBase = new ();
Модель должна контролировать своё состояние и извещать об его изменении. А как в такой реализации она сможет узнать об изменении списка?

Нужно так:
C#
11
12
13
14
15
        // описал базу данных
        public IReadOnlyList<IReadOnlyList<string>> Datas;
        private readonly List<IReadOnlyList<string>> dataList = new ();
 
        public DataBase() => Datas = new ReadOnlyCollection(dataList);
В методах Add и Remove работаем с dataList.

Цитата Сообщение от zaka4kin Посмотреть сообщение
// метод удаления из базы данных
        public void Remove(string[] str)
        {
            // удаление из коллекции
            dataBase.Remove(str);
Это не будет работать без переопределения метода сравнения.

Попробуйте:
C#
1
2
3
List<string[]> datas = new ();
datas.Add(new string[] {"1", "2"});
datas.Remove(new string[] {"1", "2"});
1
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
06.07.2023, 06:18  [ТС] 7
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Модель должна контролировать своё состояние и извещать об его изменении. А как в такой реализации она сможет узнать об изменении списка?
я думал над этим. искал в List<> событие для отслеживания. поискал в глобе.
ничего лучше кроме ObservableCollection<T>.CollectionChanged не нашёл.
решил реализовать через событие, описанное в Model
C#
1
event DataBaseChangedDelegate? DataBaseChanged;
и подписаться на него в Presenter
C#
1
dataBase.DataBaseChanged += DataBaseChanged;
Спасибо! за совет. попробую по Вашему рецепту
0
Модератор
Эксперт .NET
15470 / 10714 / 2788
Регистрация: 21.04.2018
Сообщений: 31,544
Записей в блоге: 2
06.07.2023, 11:09 8
Цитата Сообщение от zaka4kin Посмотреть сообщение
ничего лучше кроме ObservableCollection<T>.CollectionChanged не нашёл.
Есть два основных типа коллекций, позволяющих отслеживание изменений:
1) INotifyCollectionChanged - называют "Наблюдаемая коллекция";
2) IBindingList - "Привязываемый список".

ObservableCollection - это самая простая реализация INCC. Для WPF является основным типом мутабельной коллекции.
В Формах в основном используется BindingList. WPF тоже может его использовать, но ObservableCollection всё же проще.

Цитата Сообщение от zaka4kin Посмотреть сообщение
искал в List<> событие для отслеживания
List<> - это реализация IList<> "Простой индексированный список". Его реализует и T[], и многие другие коллекции. Но вот уведомления об изменении в нём не предусмотренно.

Цитата Сообщение от zaka4kin Посмотреть сообщение
решил реализовать через событие, описанное в Model
Чаще всего этот подход и будет самым верным.
Использование в свойствах Модели коллекции за состоянием которой нужно следить - это довольно громоздко и сложно.
Из реально используемых таких решений "на ум" приходит только Local.ToObservableCollection() из Контекста БД в EF.

Добавлено через 1 минуту
Цитата Сообщение от Элд Хасп Посмотреть сообщение
не будет работать без переопределения метода сравнения.
Поняли почему?
0
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
01.08.2023, 12:06  [ТС] 9
наконец-то, "дошли руки" продолжить обучение...
всё-таки бывает работа отнимает много времени и сил

Model

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
using System.ComponentModel;
 
namespace Test.Core
{
    public class DataBase
    {
        // Описал базу данных
        public BindingList<string[]> dataBase = new ();
    }
}


View

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
namespace Test.Core
{
    public class Viewer
    {
        // Описал метод вывода информации
        public void Message(string message) => Console.WriteLine(message);
    }
}


Presenter

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System.ComponentModel;
 
namespace Test.Core
{
    class Program
    {
        // Объект с базой данных
        static readonly DataBase dataBase = new ();
 
        // Объект для вывода информации
        static readonly Viewer viewer= new ();
 
        static void Main()
        {
            // Подписываемся на событие изменения базы данных
            dataBase.dataBase.ListChanged += new ListChangedEventHandler(DataBaseChanged);
 
            // Добавление в базу данных
            dataBase.dataBase.Add(new string[1]);
 
            // Изменение элемента базы данных
            dataBase.dataBase[0] = new string[8];
 
            // Добавление в базу данных
            dataBase.dataBase.Add(new string[3]);
 
            // Удаление из базы данных
            dataBase.dataBase.RemoveAt(1);
        }
 
        // Обработка события ListChanged в базе данных
        static void DataBaseChanged(object? sender, ListChangedEventArgs e)
        {
            switch (e.ListChangedType)
            {
                case ListChangedType.ItemAdded: viewer.Message("Произошло добавление элемента в базу данных!"); break;
 
                case ListChangedType.ItemDeleted: viewer.Message("Произошло удаление элемента из базы данных!"); break;
 
                default: viewer.Message("Произошло изменение элемента в базе данных!"); break;
            }
        }
    }
}


Соответствующий вывод

Кликните здесь для просмотра всего текста
Произошло добавление элемента в базу данных!
Произошло изменение элемента в базе данных!
Произошло добавление элемента в базу данных!
Произошло удаление элемента из базы данных!
0
2310 / 1672 / 327
Регистрация: 14.08.2018
Сообщений: 5,511
Записей в блоге: 4
01.08.2023, 12:21 10
Цитата Сообщение от zaka4kin Посмотреть сообщение
Presenter
Цитата Сообщение от zaka4kin Посмотреть сообщение
static void Main()
Как-то странно. Вообще-то в слое приложения должен быть View, а не Presenter...
Model - библиотека NET
Presenter - библиотека NET
View - приложение (Console, WF, WPF, Avalonia и т.д.)
0
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
01.08.2023, 18:02  [ТС] 11
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Как-то странно. Вообще-то в слое приложения должен быть View, а не Presenter...
Model - библиотека NET
Presenter - библиотека NET
View - приложение (Console, WF, WPF, Avalonia и т.д.)

что то типа этого?

Model

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
using System.ComponentModel;
 
namespace Test.Core
{
    public class Model
    {
        public BindingList<string[]> dataBase = new ();
    }
}


View

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.ComponentModel;
 
namespace Test.Core
{
    class Program
    {
        static void Main()
        {
            Presenter presenter = new ();
 
            presenter.model.dataBase.ListChanged += new ListChangedEventHandler(ChangeDataBase);
 
            presenter.model.dataBase.Add(new string[1]);
        }
 
        static void ChangeDataBase(object? sender, ListChangedEventArgs e)
        {
            Console.WriteLine("Добавление в базу данных");
        }
    }
}


Presenter

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
using System.ComponentModel;
 
namespace Test.Core
{
    public class Presenter
    {
        public Model model = new ();
    }
}


если нет, то можно Ваш вариант, для понимания?
0
2310 / 1672 / 327
Регистрация: 14.08.2018
Сообщений: 5,511
Записей в блоге: 4
02.08.2023, 08:23 12
zaka4kin,
Паттерн MVP
Особенности реализации MVP для Windows Forms

Добавлено через 1 минуту
zaka4kin, И тут на форуме есть пример - Создание программы - ООП модель, MVP
0
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
02.08.2023, 08:50  [ТС] 13
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
на форуме есть

да вот тоже тему нашёл, а там написано:

Есть всякие паттерны MVVM, MVC, MVP но они не предназначены для консольного приложения, помогите справиться с архитектурой консольного приложения.
Находил в том числе и на этом форуме что MVVM и MVC не для консоли, и не занимайтесь ерундой.

Выше написали, что я верно разобрался. Кому верить?
0
3466 / 2476 / 696
Регистрация: 02.08.2011
Сообщений: 6,720
02.08.2023, 09:15 14
Цитата Сообщение от zaka4kin Посмотреть сообщение
Кому верить?
Обычно в таком случае ищут дополнительные источники, выясняя правду.
Например,
1. MVP - Wiki
2. MVP - UI Design pattern - MSDN
3. Fowler - UI Architectures
0
2310 / 1672 / 327
Регистрация: 14.08.2018
Сообщений: 5,511
Записей в блоге: 4
02.08.2023, 09:27 15
zaka4kin, Вызывайте методы Presenter в консоли, кто вам не даёт...
Вы скорее всего не поняли сам смысл паттернов MV*. Они созданы для разделения логических частей приложения, которое упрощает разработку больших приложений в команде. Одни занимаются Model, вторые View, третие Presenter (ViewModel, Controller). И все эти группы людей практически не знают что делают другие, они видят только интерфейсы этих слоёв и работают с ними.
Распределение связей в этих паттернах такое
1. Model - сборка сама в себе, о существовании других вообще не догадывается.
2. Presenter (ViewModel, Controller) - имеет связь с Model, точнее с тем что выдано по интерфейсу в публичный доступ.
3. View - знает только о пункте 2. Пункт 1 для него не доступен на прямую.
4. Application - знает о всех слоях и задаёт взаимодействие между ними, запуская нужные сервисы для обслуживания потребностей.
1
Модератор
Эксперт .NET
15470 / 10714 / 2788
Регистрация: 21.04.2018
Сообщений: 31,544
Записей в блоге: 2
02.08.2023, 12:38 16
Andrey-MSK, не так. Вы описали за связи в паттерне MVVM. Это строго иерархический паттерн.
Например, в MVC View знает и о контролере, и о модели.

Добавлено через 2 минуты
В MVP Презентер дёргает View.
1
2310 / 1672 / 327
Регистрация: 14.08.2018
Сообщений: 5,511
Записей в блоге: 4
02.08.2023, 12:48 17
Элд Хасп, Ну бывает

Добавлено через 4 минуты
Элд Хасп, Но всё равно - Presenter ну никак не может содержать метод Main(). Вот в этом посте
0
Модератор
Эксперт .NET
15470 / 10714 / 2788
Регистрация: 21.04.2018
Сообщений: 31,544
Записей в блоге: 2
02.08.2023, 13:36 18
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Presenter ну никак не может содержать метод Main()
Класс Program - это точка запуска приложения и уровень приложения. Этот уровень не относится ни к одному из слоёв паттернов MV*. Здесь обычно происходит создание слоёв, их объектов, внедрение зависимостей.
Чтобы не было путаницы, лучше делать все слои MV* в отдельных от App проектах. К сожалению, настройки проектов для платформ GUI делают затруднительным создание View отдельно от App. Особенно для WPF. Поэтому в приложениях с GUI чаще всего App совмещён в одном проекте с View.
Совмещать App с Моделью и с VM-Controller-Presenter не имеет смысла ни при каких обстоятельствах.
0
1 / 1 / 0
Регистрация: 10.10.2021
Сообщений: 57
02.08.2023, 13:59  [ТС] 19
Элд Хасп, какой из примеров, был наиболее близок к MVP в контексте Console ?
0
Модератор
Эксперт .NET
15470 / 10714 / 2788
Регистрация: 21.04.2018
Сообщений: 31,544
Записей в блоге: 2
02.08.2023, 18:28 20
Цитата Сообщение от zaka4kin Посмотреть сообщение
какой из примеров, был наиболее близок к MVP в контексте Console ?
Ох, блин....
В общем смысле - любой паттерн подходит.
Консоль - это тип View. Во всех паттернах тип View может быть любым.

Другое дело - это вопрос о более частом применении паттерна для того или иного типа View.
MVC - исторически это первый паттерн. И, соответственно, примеров его применения для консоли гораздо больше.
Потом появились Формы и появилась потребность как-то адаптировать MVC для более удобного использования в приложениях с GUI. Появился MVP. MVVM появился уже как адаптация к WPF. Но даже его можно с успехом использовать в консоли.

Для консольного MVP я бы всё равно сделал View (консоль) в проекте с приложением. Там же сделал бы и рантайм сборку приложения - создание и связывание всех слоёв.
Но сам класс View должен быть отделён от Program.
Модель и Presenter - в отдельных проектах типа "Библиотека классов Standard".
0
02.08.2023, 18:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.08.2023, 18:28
Помогаю со студенческими работами здесь

Гостевая книга с паттерном MVC
Сделал простую гостевую книгу (Ввод имени, отзыва, сохранение и вывод данных из файла). ...

Гостевая книга с паттерном MVC
Сделал простую гостевую книгу (Ввод имени, отзыва, сохранение и вывод данных из файла). ...

Помогите с паттерном для RegExp
Есть такая строка: &lt;a class=&quot;title&quot; href=&quot;http://urlik.com/123456&quot;&gt;title 123456&lt;/a&gt; Нужно...

WPF приложение с паттерном MVVM
Добрый день Всем! Хочу сделать небольшое приложение с формулами, но нужна помощь в освоении, опыт...

Является ли срока паттерном RegEx?
Есть ли какие-то стандартные средства, которыми можно проверить, является ли пользовательская...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru