Разделил логику от интерфейса на составляющие MVC
Model:
Класс Game в котором реализованы игроки, у каждого игрока есть поле, корабли и так далее
View:
2 объекта класса TField (визуальный компонент)
Controller:
Класс GameController, который должен связывать логику игры и ходы с визуальным представлением на форме.
Именно на контроллере стал задумываться, как связать их. Определить в классе GameController объекты классов модели и визуального представления? Но как их связать? Обработку нажатия на клетку в поле, отправку координат X и Y в класс Game и обратно получить ответ, обработав попадание/не попадание?
Я частично понял, как реализовать все это. У нас есть цепочка:
Представление -> Контроллер -> Модель
Представление вызывает клик и отправляет контроллеру событие о выстреле. Контроллер передает информацию об это модели на обработку. Но как сделать обновление Представления после изменений в Модели я так и не понял.
Я так понимаю, что нужно создать слушателя/-ей, которые будут вызываться из Модели при обновлении данных. Но это значит, что Модель должна содержать ссылку на Представление, что по сути перечит MVC, если Модель должна не знать о Представлении. Есть мысли?
Ответ
Смотрите. Вам нужен по идее event или Listener, или как там этот паттерн называется.
Суть такова.
Модель выставляет метод Subscribe(), в который можно передать callback, который будет вызван при изменении свойства. Представление знает о модели, и подписывается на её изменения. Таким образом, модель ничего не знает о представлении, но может дёрнуть это самое представление, когда что-то поменялось.
Пример на коленке:
class Model
{
public:
typedef int Token;
Token subscribe(std::function
void unsubscribe(Token token)
{
callbacks.erase(token);
}
private:
std::map
// это дёрнет все 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);
}
};
Комментариев нет:
Отправить комментарий