Смотрю демонстрационное C#-приложение использующее MVC. И вижу, что при каждом щелке на кнопке "Show.." там создаётся объект Controller, а внутри него создаются объект Model и объект View.
1.Так поступают в реальных приложениях (т.е. многократное создание модели)?
2.И правильно ли я понимаю, что если приложение открывает некий "проект", то понятие "проект" — это и есть модель ?
3.В сети все примеры на .NET или Java и все игрушечные. Нет ли ссылки на C++-реализацию ?
4.Нет ли C++ библиотеки для реализации MVC (отдельно, а не в составе монстров типа MFC)?
Здравствуйте, Аноним, Вы писали:
А>Смотрю демонстрационное C#-приложение использующее MVC. И вижу, что при каждом щелке на кнопке "Show.." там создаётся объект Controller, а внутри него создаются объект Model и объект View. А>1.Так поступают в реальных приложениях (т.е. многократное создание модели)? А>2.И правильно ли я понимаю, что если приложение открывает некий "проект", то понятие "проект" — это и есть модель ? А>3.В сети все примеры на .NET или Java и все игрушечные. Нет ли ссылки на C++-реализацию ? А>4.Нет ли C++ библиотеки для реализации MVC (отдельно, а не в составе монстров типа MFC)?
Каждая конкретная модель должна быть в одном экземпляре (лучше так ModelManager->registr ... unregistr .. etc),
проект это не модель
4. Напиши более конкретно что и как тебе нужно, я помогу тебе сделать подходящий для тебя MVC каркас.
Re[2]: MVC: почему модель многократно создаётся !?
Здравствуйте, Stormblast, Вы писали:
S>Здравствуйте, Аноним, Вы писали:
S>Каждая конкретная модель должна быть в одном экземпляре (лучше так ModelManager->registr ... unregistr .. etc), S>проект это не модель
S>Напиши более конкретно что и как тебе нужно, я помогу тебе сделать подходящий для тебя MVC каркас.
Задача:
1.Открыв "проект", пользователь может выбрать подходящие параметры для
некоторого алгоритма (конкретно — пощелкать мышкой в модальном диалоговом окне).
2.Выбрав праметры, пользователь может
посмотреть на результат счёта(конкретно — щёлкнуть на кнопку "Calc" на главной форме и увидеть некоторый график
на ней же).
3.Пользователь может сохранить "проект" с текущими параметрами счёта(конкретно — в виде xml/ini/txt файла).
То, что я сейчас построил выглядит так:
1. Два "вида:
а)главное окно с графиком
б)диалоговое окно с параметрами алгоритма
2. Два "контроллера":
а)первый "контроллер" обслуживает "вид" а) (конкретно — принимает от "вида" сообщение DO_CALC
и вызывает у модели метод DoCalc() ).
б)второй "контроллер" обслуживает вид б) (конкретно — пинимает от вида сообщение CHANGE_PARAM
, забирает параметры из контролов формы, и передаёт их в метод модели SetParam(..)
3. Одна модель:
Оповещает зарегистрированые виды, после отработки соих методов DoCalc() и SetParam()
Имеет методы для оперций с "проектом": Open,SaveAs .. , которые вызываются контроллером а).
Т.е. я считал, что в данном случае "модель" это и есть "проект" ( или собственно "приложение", которое может открывать некий "проект"). Вся MVC-троица создаётся один раз при старте приложения в ф-ии WinMain, там же все участники получают нужные им указатели. Причём соблюдается правило:
— "контроллер" знает полные типы и "модели"
— "вид" знает полный тип модели и минимальный интерфейс "контроллера"
— "модель" знает минимальный интерфейс вида (ISubscriber)
Буду благодарен за любые конструктивные комментрарии.
Re[3]: MVC: почему модель многократно создаётся !?
Здравствуйте, shvonder, Вы писали:
S>Задача: S>1.Открыв "проект", пользователь может выбрать подходящие параметры для S>некоторого алгоритма (конкретно — пощелкать мышкой в модальном диалоговом окне). S>2.Выбрав праметры, пользователь может S>посмотреть на результат счёта(конкретно — щёлкнуть на кнопку "Calc" на главной форме и увидеть некоторый график S> на ней же). S>3.Пользователь может сохранить "проект" с текущими параметрами счёта(конкретно — в виде xml/ini/txt файла).
S>То, что я сейчас построил выглядит так: S>1. Два "вида: S> а)главное окно с графиком S> б)диалоговое окно с параметрами алгоритма
S>2. Два "контроллера": S> а)первый "контроллер" обслуживает "вид" а) (конкретно — принимает от "вида" сообщение DO_CALC S> и вызывает у модели метод DoCalc() ). S> б)второй "контроллер" обслуживает вид б) (конкретно — пинимает от вида сообщение CHANGE_PARAM S> , забирает параметры из контролов формы, и передаёт их в метод модели SetParam(..)
S>3. Одна модель: S> Оповещает зарегистрированые виды, после отработки соих методов DoCalc() и SetParam() S> Имеет методы для оперций с "проектом": Open,SaveAs .. , которые вызываются контроллером а).
S>Т.е. я считал, что в данном случае "модель" это и есть "проект" ( или собственно "приложение", которое может открывать некий "проект"). Вся MVC-троица создаётся один раз при старте приложения в ф-ии WinMain, там же все участники получают нужные им указатели. Причём соблюдается правило: S> — "контроллер" знает полные типы и "модели" S> — "вид" знает полный тип модели и минимальный интерфейс "контроллера" S> — "модель" знает минимальный интерфейс вида (ISubscriber)
S>Буду благодарен за любые конструктивные комментрарии.
Видно, что понимание есть ...
Как, я понял из описания "проект" это некая сущность тогда она может быть моделью, например ProjectModel наследуем от AbstractModel(базовый класс всех моделей с мин набором методов), модель это тупое хранилище данных.
Контроллеры, например CalcController и ParamController от базого AbstractController, может создавать, обслуживать models и так же views (либо использовать паттерн Factory, где например ModelFactory будет создавать и регистрировать models) или использовать ModelManager для обслуживания модели , например ModelManager->regisrt(AbstactModel) unreg() and etc, ModelManager будет делать delete model, когда на неё не останется ссылок, т.е. юзер закрыл окна которые по цепочки потянут контроллеры а те в свою очередь начнут делать ModelManager->unregist(models). Добавлять ссылки на модели можно при создании контроллера например Controller->init();
init()
{
model = ModelManager->getModel(codeModel(например ProjectModel->getCode() или ContsModelName::ProjectModel))
if(model == null){
создаем model и регистрируем в ModelManager->regisrt(model);
}
и так все модели ... этот конечно псевдо код
}
View, от AbstractView не содержит ни какой логики только отображение и обработка событий от юзера.
Предлагаю следующую связь Model<->Controller<->View, т.е. модель не знает о вью и наоборот все делается через контроллер вся БЛ в контроллерах, это удобно если большой клиент где у контроллера много моделей и вьюшек.
Для простых проектов подойдет просто Model<->View ...
рассмотрим первый вариант.
Использование:
имеем Application наш главный класс
Application->start()
start(){
сделаем основной контроллер типа Workbench
Workbench->init() он создает базовое View(окно и т.п.).
пока нет ни моделей на конкретных контроллеров ...
(можно сделать, что бы что то открывалось по дефолту)
далее когда юзер жмет например создать Project, Workbench ловит мессадж от gui и создает соответствующий контроллер который начинает слушать свои модели, создает views и процесс пошел ...
}
}
если будешь делать дерево или список "projects" то возможно нужно будет сделать либо ListModel либо при регистрации сделать ModelManager->regisrt(model) где
regisrt(){
model->getNameModel + model->getObject()->getID() т.е. ещё добавить идентификацию конкретного project
}
Re[4]: MVC: почему модель многократно создаётся !?
1. S>[..]модель это тупое хранилище данных.
Когда в методе модели Model::Calc() отрабатывает алгоритм, то образуется несколько больших массивов данных.
Их нужно только отрисовать и пос ле этого уничтожить.
Как передать во view эти массивы ? Собственно, есть два варианта:
а) Отправка указателя на эти массивы в прямо в нотификации(типа как в Windows Lparam,WParam для сообщения WM_COPYDATA). Но тогда Вид будет применять reinterpret_cast<>. См. пример ниже.
б) Сохранение всего этого в Модели. Вид, когда получает ссобщение об изменении модели, начинает её
опрашивать, и забирает массивы. Но кто будет уничтожать их внутри Модели ?
Сама Модель не знает, как когда Вид закончит рисование и неможет определить момент. когда можно
убить массивы. А Вид, не должен по идее давать Модели команды на изменение(Model::ClearResultOfCalc() ).
Или вид должен послать сообщение контроллеру, мол, отрисовался, а тот уже вызовет Model::ClearResultOfCalc() ?
Как-то сложно.
Вот примерно первый вариант:
struct Command
{
int code;
void *ptr;
};
struct ArrayAndParamStruct
{
valarray<> *arr1,*arr2;
Param * param;
};
//В модели
Model::Calc(Param& param)
{
valarray<double> arr1,arr2;
DoCapculation(param,&arr1,&arr2);//отработка алгоритма
//упаковываем все указатели в структуру, чтобы можно было отправить указатель на неё
ArrayAndParamStruct aaps = {};
aaps.arr1 = &arr1;
aaps.arr2 = &arr2;
aaps.param = ¶m;
//формируем отправляемое Сообщение,
Command cmd = {};
cmd.code = WAS_RECALC;
cmd.ptr = &aaps; //ArrayAndParamStruct* -> void*
NotifyAll(cmd);
}
//В Виде который принял это сообщение
View::ModelChanged(Command & cmd)
{
case cmd.code == WAS_RECALC:
OnRecalc(reinterpet_cast<ArrayAndParamStruct*>(cmd.ptr) );//void* -> ArrayAndParamStruct* break;
}
S>Контроллеры, например CalcController и ParamController от базого AbstractController, может создавать, обслуживать models и так же views [..] S>Предлагаю следующую связь Model<->Controller<->View, т.е. модель не знает о вью и наоборот все делается через контроллер вся БЛ в контроллерах, это удобно если большой клиент где у контроллера много моделей и вьюшек.
Т.е. всё создаётся в Контроллере ? Имеется ввиду именно MVC, а не MVP, т.е. чтобы логика рисования была именно во View, а не в Контроллере.
3. В каждом проекте нужно сделать постоянно делать одно и тоже: породить Модель, Вид, Контроллер от базовых и связать их. Нет ли библиотеки для этого ( без привязки к GUI, pure C++)? Примерно, как в MFC сделано CDocument, CView, но в MFC Документ/Вид прямо в GUI-библиотеке сидят.
Re[5]: MVC: почему модель многократно создаётся !?
Т.е. фактичеки весь гуй — это процесс создания контроллеров ?
Создали Конроллер, он создал Вид, затем создал(или запросил) Модель, затем связал всю триаду ссылками.
Уничтожили Вид, об этом узнаёт контроллер, уничтожает (или отписывает) Модель, и уничтожает себя (или сообщает менеджеру).
И местом хранения Вида и Модели (если нет менеджера Моделей) является Контроллер ? И есть, наверное, какой нибудь обший менеджер контролеров ?
Здравствуйте, shvonder, Вы писали:
S>Когда в методе модели Model::Calc() отрабатывает алгоритм, то образуется несколько больших массивов данных.
Модель не должна ничего делать, напиши для бизнес-логики например CalcService->Calc(data ...), который будет вызывать контроллер
и сэть готовые данные в модель ...
S>Их нужно только отрисовать и пос ле этого уничтожить.
после чего модель кидает сообщение об изменении (например class Event<T> который будет может содержать тип сообщения, св-ва, данные : ADD, CHANGED, REMOVE ... property, Data* data(void* data и потом динамик_каст)), и все контроллеры которые подписаны на данную модель, словив сообщение перерисовывают Views ...
S>Как передать во view эти массивы ?
например class Event<T> который будет может содержать тип сообщения, св-ва, данные : ADD, CHANGED, REMOVE ... property, Data* data(или грубо: void* data и потом динамик_каст, а в Data или void* можешь запихать передачу своих данных или т.п.
S> Сама Модель не знает, как когда Вид закончит рисование и неможет определить момент. когда можно S> убить массивы.
Модель это и есть данные или массив данных и т.п. сделай ее само-убиваюмою т.е. можно добавить подсчет ссылок как только все отписались, в деструкторах контроллеров вызывать ModelManager->unregister() модель делает себе Relese(){delete this грубо, ну типа того }
S> А Вид, не должен по идее давать Модели команды на изменение(Model::ClearResultOfCalc() ).
нет в том варианте что я тебе привел вид не знает про модель он работает с контроллером ...
S> Или вид должен послать сообщение контроллеру, мол, отрисовался, а тот уже вызовет Model::ClearResultOfCalc() ?
да, и если тебе нужно отчистить вид то очищаем модель и вид должен в соответствии с пустыми данными отчистить gui.
S> Как-то сложно.
Повторяюсь: Для не больших проектов подойдет Model<->View
S>Вот примерно первый вариант:
S>
S>struct Command
S> {
S> int code;
S> void *ptr;
S> };
S> struct ArrayAndParamStruct
S> {
S> valarray<> *arr1,*arr2;
S> Param * param;
S> };
S>//В модели
S> Model::Calc(Param& param)
S> {
S> valarray<double> arr1,arr2;
S> DoCapculation(param,&arr1,&arr2);//отработка алгоритма
S> //упаковываем все указатели в структуру, чтобы можно было отправить указатель на неё
S> ArrayAndParamStruct aaps = {};
S> aaps.arr1 = &arr1;
S> aaps.arr2 = &arr2;
S> aaps.param = ¶m;
S> //формируем отправляемое Сообщение,
S> Command cmd = {};
S> cmd.code = WAS_RECALC;
S> cmd.ptr = &aaps; //ArrayAndParamStruct* -> void*
S> NotifyAll(cmd);
S> }
S>//В Виде который принял это сообщение
S> View::ModelChanged(Command & cmd)
S>{
S> case cmd.code == WAS_RECALC:
S> OnRecalc(reinterpet_cast<ArrayAndParamStruct*>(cmd.ptr) );//void* -> ArrayAndParamStruct*
S> break;
S>}
S>
1 модель не должна ничего делать
2 избегай int code; простых типов лучше Type type где ADD, CHANGED, REMOVE etc.
3 виде сделай в общем интефейсе для всех видов метод например updateData() который будет выводить данные на GUI и т.п.
S>>Контроллеры, например CalcController и ParamController от базого AbstractController, может создавать, обслуживать models и так же views [..] S>>Предлагаю следующую связь Model<->Controller<->View, т.е. модель не знает о вью и наоборот все делается через контроллер вся БЛ в контроллерах, это удобно если большой клиент где у контроллера много моделей и вьюшек. S>Т.е. всё создаётся в Контроллере ? Имеется ввиду именно MVC, а не MVP, т.е. чтобы логика рисования была именно во View, а не в Контроллере.
ну пусть View как хотеч полученные от контроллера данные так и рисует ...
S>3. В каждом проекте нужно сделать постоянно делать одно и тоже: породить Модель, Вид, Контроллер от базовых и связать их. Нет ли библиотеки для этого ( без привязки к GUI, pure C++)? Примерно, как в MFC сделано CDocument, CView, но в MFC Документ/Вид прямо в GUI-библиотеке сидят.
возможно уже и есть, но тут ничего сложного нет все это реализуемо ... и конечно можно без привязки к конкретному гуи (MFC) для можно например написать свой Control Processor использовать декоратор и т.д. и т.п.
Re[6]: MVC: почему модель многократно создаётся !?
2. S>например class Event<T> который будет может содержать тип сообщения, св-ва, данные : ADD, CHANGED, REMOVE ... property, Data* data(или грубо: void* data и потом динамик_каст, а в Data или void* можешь запихать передачу своих данных или т.п.
Принято.
3. S>[..]после чего модель кидает сообщение об изменении [..] все контроллеры которые подписаны на данную модель, словив сообщение перерисовывают Views ...
S>нет в том варианте что я тебе привел вид не знает про модель он работает с контроллером ...
S>Предлагаю следующую связь Model<->Controller<->View, т.е. модель не знает о вью и [..] все делается через контроллер вся БЛ в контроллерах[..]
4. S>Модель не должна ничего делать, напиши для бизнес-логики например CalcService->Calc(data ...), который будет вызывать контроллер и сэть готовые данные в модель ... S>1 модель не должна ничего делать
Стоп-стоп. Что ещё за CalcService ? Откуда он в MVC ?
И почему Модель не должна ничего делать ? Ведь Модель — это медиатор
предметной области. Т.е. если, например, в предметной области есть определённый алогоритм, то Модель должна уметь его вызвать.
Ты по сути говоришь, что вся логика соседоточена в Контроллере. Но! Если запрос на изменение Модели приходит из другого Вида ? (конкретно, на двух разных формах есть кнопка "Calc"). Если метод Calc() есть у модели, тогда оба Контроллера его смогут вызвать. А у тебя выходит, что весь вызов алгоритма происходит в каком-то определённом Контроллере, а Контроллеры о друг друге не знают.
Судя по-тому, что у тебя появился CalcService(), у тебя оба контролера будут обращаться именно в методу CalcService::Calc().
Но тогда роль Модели (т.е. медиатора предметной области) играет CalcService() !
Re[7]: MVC: почему модель многократно создаётся !?
Здравствуйте, shvonder, Вы писали:
S>>Предлагаю следующую связь Model<->Controller<->View, т.е. модель не знает о вью и [..] все делается через контроллер вся БЛ в контроллерах[..]
S>Судя по всему, ты веришь Бодягину
MVC я уже давно использую и больше верю себе ... пожалуй сначала прочту статьи.
S>4. S>>Модель не должна ничего делать, напиши для бизнес-логики например CalcService->Calc(data ...), который будет вызывать контроллер и сэть готовые данные в модель ... S>>1 модель не должна ничего делать
S>Стоп-стоп. Что ещё за CalcService ? Откуда он в MVC ?
CalcService в данном случае это сервисный класс обслуживающий какую то область БЛ.
S>И почему Модель не должна ничего делать ? Ведь Модель — это медиатор S>предметной области. Т.е. если, например, в предметной области есть определённый алогоритм, то Модель должна уметь его вызвать.
Боюсь показаться старомодным , но у меня модель это всегда только данные.
хотя я не сторонник жесткого MVC, у меня в разных проектах, где использовался mvc была своя наиболее соответствующая задачам и принципам ООП реализация.
S>Ты по сути говоришь, что вся логика соседоточена в Контроллере. Но! Если запрос на изменение Модели приходит из другого Вида ? (конкретно, на двух разных формах есть кнопка "Calc"). Если метод Calc() есть у модели, тогда оба Контроллера его смогут вызвать. А у тебя выходит, что весь вызов алгоритма происходит в каком-то определённом Контроллере, а Контроллеры о друг друге не знают.
я писал про связь M<->C<->V т.е. View общается только с контроллером, а контроллер дергает CalcService->Calc и сеттит данные в модель ...
S>Судя по-тому, что у тебя появился CalcService(), у тебя оба контролера будут обращаться именно в методу CalcService::Calc(). S>Но тогда роль Модели (т.е. медиатора предметной области) играет CalcService() !
Контроллеры будут обращаться к CalcService через синглетон например ServiceLocator::Instance()->calc(){CalcService->calc};
где ServiceLocator обеспечивает обращение к сервисным методам через одну точку (т.е. только через себя) ...
а модель остается тупым хранилищем данным и она не должна больше ничего делать ...