#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::functioncallback) { 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); } };
Комментариев нет:
Отправить комментарий