Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
#1

Консольное меню MVC - C++

06.05.2014, 22:43. Просмотров 1271. Ответов 14
Метки нет (Все метки)

С моего последнего проектика прошло не так уж много времени, а я вновь здесь и уже с новыми исходниками
Снова паттерны и каркас MVC, и снова я жду от вас комментариев

Итак, мой новый проект является, грубо говоря, библиотекой для создания консольного меню. То есть, Вы, как пользователь, хотите создать к примеру маленькую игрушку в консольном приложении, и вам 100% понадобится Меню для вашего серьезного проекта. Как же быть? Писать с нуля? Нет конечно, на помощь вам приходит папа bretbas!

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

Классы:
Controller - Абстрактный класс контроллера. Имеет виртуальную операцию execute() для реализации паттерна Команда(Command). Так же имеет статическую функцию initialize(...) для инициализации контроллера нужными данными, и статическую функцию run() для управления меню с пользователем.
ItemStart - Конкретный класс контроллера. Реализует операцию execute()
ItemOption - Конкретный класс контроллера. Реализует операцию execute()
ItemExit - Конкретный класс контроллера. Реализует операцию execute()

Model - Абстрактный класс модели. Реализует паттерн Наблюдатель(Observer) и является субъектом за которым следят наблюдатели.
ModelMenu - Конкретный класс модели. Знает о названии пунктов меню, о положении текущего курсора, о координатах показа меню на экране и тд. Использует функции set/get.

View - Абстрактный класс представления. Является наблюдателем в паттерне Наблюдатель(Observer), поэтому использует виртуальную операцию update(), для реализации ее в подклассах. Каждый раз, когда будет изменяться Model, будет вызвана эта операция. Так же инициализирует простейшую графику в консоле.
ViewMenu - Конкретный класс представления. Реализует операцию update(), для отображения меню на экране.


Применение:
К примеру Вы в вашем грандиозном проекте решили создать меню из 3 пунктов, а именно Start,Option,Exit. Как же Вам создать их, используя мою библиотеку?
Да очень просто!
Во-первых, нужно создать три подкласса класса Controller. Давайте назовем их ItemStart,ItemOption,ItemExit.
Во-вторых, нужно написать соответствующие действие по выбронному пункту меню правильно? А значит нужно реализовать переопределенную операцию execute() для каждого подкласса.
В-третьих, в основном коде, нужно инициализировать Модель и Представление:
C++
1
2
3
4
...
    ModelMenu   *model  = new ModelMenu();          // Создаем Модель Меню
    View        *view   = new ViewMenu(model);      // Создаем Представление Меню
...
В-четвертых, инициализируем контроллер моделью и нужными нам координатами для вывода меню на экране:
C++
1
2
3
...
    Controller :: initialize(model,40,12);          // Инициализируем Контроллер данными
...
В-пятых инициализируем каждый пункт с параметрами, которые являются названию пунктов меню:
C++
1
2
3
4
5
6
...
    Controller* item[3];                            // Создаем 3 Пункта Меню
    item[0] = new ItemStart("Start");               // Start
    item[1] = new ItemOption("Option");             // Option
    item[2] = new ItemExit("Exit");                 // Exit
...
Ну и соответственно запустим всю систему
C++
1
2
3
4
...
    Controller :: run();                            // Запуск системы
...
...
Просто? Я думаю да

А теперь я хочу чтобы вы прокоментировали мои исходники, правильно ли я разложил все на 3 полки - MVC? Или что-то нужно добавить/убрать/изменить?

Я не шел к цели, чтобы я работал на MVC. Я шел к цели, чтобы MVC работал на меня, где-то его изменить, где-то что-то убрал, но суть каркаса MVC в моей задаче НА МОЙ ВЗГЛЯД осталась та же.
Но опять же, это на мой взгляд. Так вот мне нужно узнать ваш взгляд на данную задачу Прикрепляю проект
0
Вложения
Тип файла: 7z PatternsMenu.7z (548.6 Кб, 38 просмотров)
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.05.2014, 22:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Консольное меню MVC (C++):

Консольное меню - C++
Здравствуйте кто может помочь с консольным меню. Расклад таков. Верхнее меню должно состоять из 6 пунктов. 1) --> Ауди --- --- ...

TextUserInterface меню(Консольное приложение) - C++
Здравствуйте, есть меню в котором 5 пунктов. В пункте 1 есть есть аналогичное подменю с такой же структурой. Проблема в том, что при...

Создать консольное меню с более чем 10-ю пунктами - C++
Есть такая проблема, нужно создать меню в консоле, где более 10 пунктов. Когда вводишь числа с 1-9 всё работает прекрасно, но начиная с 10,...

подскажите - консольное меню не реагирует на нажатие клавиш (case) - C++
вот код, mv 2008 компилируется без ошибок, но при выборе 1, 2, 3 или 4 в меню ничего происходит где косяк? #include "stdafx.h" ...

Консольное приложение - C++
Здравствуйте! Имеется консольное приложение, которое при наборе команды "start" выполняет запуск программы. Проблема в том, что пока я...

консольное окно - C++
Заранее извеняюсь за то что задаю тупой вопрос, как надо изменить размеры (т.е. высоту и ширину) консольного окна?? Если можно приведите...

14
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
08.05.2014, 00:03  [ТС] #2
есть тут кто?)
0
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
08.05.2014, 13:14 #3
Bretbas, Да, да..

Не мог бы ты выложить сорсы на github.com или bitbucket.org? У меня проблемка с кодировкой.

UPD: а нет, QtCreator потянул cp1251 (просто я с вимом налажал)
0
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
09.05.2014, 23:24  [ТС] #4
outoftime, не понял?
0
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
10.05.2014, 23:37  [ТС] #5
ну где же ваши комменты?)
0
uhx
60 / 60 / 6
Регистрация: 11.07.2013
Сообщений: 304
11.05.2014, 02:04 #6
Цитата Сообщение от Bretbas Посмотреть сообщение
ну где же ваши комменты?)
Просто никому не нужна эта библиотека))
Кому надо - тот сделает сам и под себя, так даже интереснее. Да и не трудно это.
0
MastAKK
145 / 136 / 12
Регистрация: 13.10.2012
Сообщений: 592
11.05.2014, 02:29 #7
А можно скрины примера меню?
Влом качать и делать самому
0
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
11.05.2014, 23:52  [ТС] #8
только завтра могу скинуть скрины)

на счет библиотеки...я же это так просто сказал)конечно же я ее не буду выпускать ахах)мне просто интересно ваше мнение по поводу кода,рефакторинга и тд
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
12.05.2014, 00:05 #9
в файле Model.h есть
C++
1
#include "View.h"
так вот его надо убрать и сделать forward declaration
C++
1
class View;
а уже в файле Model.cpp сделать
C++
1
#include "View.h"
____________________________________________________________________________________________
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void Model :: remove_observer(View* observer)
{
    std :: vector<View*> :: iterator i;
 
    for (i = observers_.begin( ) ; i != observers_.end( ) ; i++)
    {
        if(*i == observer)
        {
            observers_.erase(i);
            break;
        }
    }
}
1. зачем сравнивать View по значению?
2. после модификации вектора итераторы становятся недействительными
____________________________________________________________________________________________
очень много где в коде параметры передаются по значению вместо ссылки на константу
0
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
12.05.2014, 00:51  [ТС] #10
Jupiter, спасибо за ответ,все поправлю)
Но есть вопросы:
1.Зачем делать предварительное объявление и инклуд класть в .cpp файл?Почему именно так?
2.Значит нужно делать такую схему предварительного объявления везде,где подключается файл?К примеру в файле Controller.h подключается файл ModelMenu.h,значит нужно так же сделать forward
declaration и добавить иклуд ModelMenu в Controller.cpp?
3.В методе remove_observer(View* observer) я пытаюсь удалить из вектора элемент observer.Вы имеете ввиду не сравнивать по значению как?А как нужно?
4. Что значит итератор не действительный?И как это исправить?
5. А где именно в программе параметры передаются по значению?Я вроде почти везде использовал ссылки
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
12.05.2014, 01:26 #11
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Bretbas Посмотреть сообщение
1.Зачем делать предварительное объявление и инклуд класть в .cpp файл?Почему именно так?
потому что #include это простая подстановка содержимого файла. тому кто инклудит Model.h нужна только модель, а ему вместе с моделью ещё зачем-то впаривают содержимое View.h

Добавлено через 4 минуты
Цитата Сообщение от Bretbas Посмотреть сообщение
2.Значит нужно делать такую схему предварительного объявления везде,где подключается файл?К примеру в файле Controller.h подключается файл ModelMenu.h,значит нужно так же сделать forward
declaration и добавить иклуд ModelMenu в Controller.cpp?
не смотрел, но общие принципы таковы:
- хедер должен как можно меньше инклудить другие хедеры
- если в хедере используется лишь указатель на класс следует использовать forward declaration

Добавлено через 45 секунд
Цитата Сообщение от Bretbas Посмотреть сообщение
3.В методе remove_observer(View* observer) я пытаюсь удалить из вектора элемент observer.Вы имеете ввиду не сравнивать по значению как?А как нужно?
в векторе у тебя указатели на View, так вот и сравнивай указатели

Добавлено через 5 минут
C++
1
2
3
4
5
6
void Model::remove_observer(View* observer)
{
    std::vector<View*>::iterator it = std::find(observers_.begin(), observers_.end(), observer);
    if (it != observers_.end())
        observers_.erase(it);
}
Цитата Сообщение от Bretbas Посмотреть сообщение
5. А где именно в программе параметры передаются по значению?Я вроде почти везде использовал ссылки
да в том же Controller
0
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
12.05.2014, 01:33  [ТС] #12
В контроллере из за того,что я сделал поле ModelMenu* model_ статическим?В функции initialize() передаю указатель вроде.Не пойму я.Скорее всего я не понимаю вас по поводу 5 вопроса(
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,292
22.06.2014, 17:45 #13
Цитата Сообщение от Bretbas Посмотреть сообщение
Скорее всего я не понимаю вас по поводу 5 вопроса(
Наверное он имел в виду передачу std::string по значению, 17 строка, Controller.cpp и подобные ситуации.

А в целом, если оставить в стороне мелкие придирки, код хороший и аккуратный.
1
gray_fox
What a waste!
1521 / 1226 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
22.06.2014, 18:05 #14
Bretbas, стоило бы очистить проект от временных файлов перед тем, как выкладывать.
1
Bretbas
Каждому свое
344 / 114 / 31
Регистрация: 05.08.2013
Сообщений: 1,221
Завершенные тесты: 1
22.06.2014, 22:13  [ТС] #15
DrOffset, спасибо
0
22.06.2014, 22:13
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.06.2014, 22:13
Привет! Вот еще темы с ответами:

Консольное приложение - C++
как можно поставить обработчики на нажатие клавишь ctrl+c и того типа

Консольное приложение на С++ - C++
народ помогите плиз решить проблему написал игру под консоль. типа змейки как добавить функцию типа рестарт (если проиграл или выиграл)...

консольное приложение - C++
Помогите разобраться с задачкой! Написать на С++ код консольного приложения, реализующий в главной функции ввод с клавиатуры в...

Консольное окно - C++
STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &amp;si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &amp;pi, sizeof(pi)...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru