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