При написании графических интерфейсов я часто сталкиваюсь со следующей проблемой: предположим, что у вас есть модель и контроллер. Контроллер имеет виджет W
, который используется для отображения свойства X
модели.
Поскольку модель может быть изменена извне контроллера (могут быть другие контроллеры, использующие одну и ту же модель, операции отмены и т.д.), контроллер прослушивает изменения в модели. Контроллер также прослушивает события в виджете W
и соответственно обновляет свойство X
.
Теперь происходит следующее:
- изменяется значение в
W
- генерируется событие, вызывается обработчик в контроллере
- контроллер устанавливает новое значение для
X
в модели - модель излучает события, потому что она была изменена.
- контроллер получает событие изменения из модели
- контроллер получает значение
X
и устанавливает его в виджет - перейти 1.
Для этого существует несколько возможных решений:
- Измените контроллер, чтобы установить флаг при обновлении модели, и не реагируйте на какие-либо события из модели, если этот флаг установлен.
- Временно отключите контроллер (или сообщите моделе не отправлять какие-либо события в течение некоторого времени)
- Заблокируйте все обновления из виджета
В прошлом я обычно отправлялся на вариант 1., потому что это самая простая вещь. У этого есть недостаток загромождения ваших классов флагами, но другие методы также имеют свои недостатки.
Только для записи у меня была эта проблема с несколькими инструментами GUI, включая GTK +, Qt и SWT, поэтому я думаю, что это довольно инструментарий-агностик.
Любые лучшие практики? Или архитектура, которую я использую просто неправильно?
@Shy: это решение для некоторых случаев, но вы по-прежнему получаете раунд лишних событий, если X
изменен извне контроллера (например, при использовании шаблона команды для отмены/повтора), потому что тогда значение изменилось, W
обновлено и запускает событие. Чтобы предотвратить другое (бесполезное) обновление модели, событие, генерируемое виджетами, должно быть проглочено.
В других случаях модель может быть более сложной, и простая проверка того, что именно изменилось, может оказаться невозможной, например. сложное древовидное представление.