Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

MVC для игры морской бой

#cpp #mvc #проектирование


Разделил логику от интерфейса на составляющие MVC

Model:

Класс Game в котором реализованы игроки, у каждого игрока есть поле, корабли и так далее

View:

2 объекта класса TField (визуальный компонент)

Controller:

Класс GameController, который должен связывать логику игры и ходы с визуальным представлением
на форме.

Именно на контроллере стал задумываться, как связать их. Определить в классе GameController
объекты классов модели и визуального представления? Но как их связать? Обработку нажатия
на клетку в поле, отправку координат X и Y в класс Game и обратно получить ответ, обработав
попадание/не попадание?

Я частично понял, как реализовать все это. У нас есть цепочка:


  Представление -> Контроллер -> Модель


Представление вызывает клик и отправляет контроллеру событие о выстреле. Контроллер
передает информацию об это модели на обработку. Но как сделать обновление Представления
после изменений в Модели я так и не понял.

Я так понимаю, что нужно создать слушателя/-ей, которые будут вызываться из Модели
при обновлении данных. Но это значит, что Модель должна содержать ссылку на Представление,
что по сути перечит MVC, если Модель должна не знать о Представлении. Есть мысли?
    


Ответы

Ответ 1



Смотрите. Вам нужен по идее event или Listener, или как там этот паттерн называется. Суть такова. Модель выставляет метод Subscribe(), в который можно передать callback, который будет вызван при изменении свойства. Представление знает о модели, и подписывается на её изменения. Таким образом, модель ничего не знает о представлении, но может дёрнуть это самое представление, когда что-то поменялось. Пример на коленке: class Model { public: typedef int Token; Token subscribe(std::function callback) { max_token++; callbacks[max_token] = callback; return max_token; } void unsubscribe(Token token) { callbacks.erase(token); } private: std::map> callbacks; Token max_token = -1; // это дёрнет все callback'и void notifyall() { for (auto& kv : callbacks) kv.second(); } }; class View { Model* model; Model::Token token; //... View(Model* model) : model(model) { token = model->subscribe([this] { OnModelUpdate(); }); } ~View() { model->unsubscribe(token); } };

Комментариев нет:

Отправить комментарий