c ++ "двунаправленный" шаблон наблюдателя - PullRequest
4 голосов
/ 24 ноября 2010

Я читал о том, как реализовать правильный MVC в приложении C ++, и в основном дошел до того, что есть 2 способа реализации этого:

  • образец наблюдателя
  • сигнал / слот

Однако в обоих случаях все примеры, которые я прочитал, следуют структуре, в которой субъект может измениться и уведомить своего наблюдателя (наблюдателей), но наблюдатель никогда не меняет субъекта. Теперь в этом случае возникает несколько «проблем».

Допустим, у меня есть класс с именем Text (компонент модели), другой класс с именем TextEditor (компонент GUI), который в некотором роде отображает «Текст» И должен иметь возможность изменять его, и несколько других классов, которые могут изменять «Текст» 'также.

Правильно, поэтому я использую шаблон наблюдателя, делаю 'Text' субъектом, а 'TextEditor' наблюдателем. Ничего страшного.

Если «Текст» изменен каким-либо образом, Text вызывает Text :: notify (), и мой TextEditor отразит это изменение. Хорошо.

Теперь, что если я использую TextEditor для изменения текста?

TextEditor знает о Text, поэтому он вызывает что-то вроде textInstance.setText (...) ... и в конце setText «Text» вызывает notify, а «TextEditor» уведомляется об изменениях, которые он сделал сам! «Текст» не может даже отправить уведомление всем, кроме «TextEditor», потому что он не должен знать о своих наблюдателях!

У меня такое ощущение, что это не правильно, не "чисто", даже из соображений производительности. Держу пари, есть лучший способ реализовать это, но я застрял. У кого-нибудь есть намеки?

Я на самом деле не смотрю на готовую реализацию C ++, а больше на понимание того, как я должен видеть вещи правильно.

1 Ответ

4 голосов
/ 24 ноября 2010

шаблон чистый.Вы делаете предположение, что TextEditor сейчас делает то, что делает setText, и поэтому не должны быть уведомлены.Что делать, если текст был заморожен и отказывается изменять себя.Текст также может быть своего рода логгером, который добавляет любой новый текст и добавляет метку времени и т. Д.

Таким образом, TextEditor вполне может «попросить» Text сделать что-то, а затем проверить, каков результат.Поэтому TextEditor не уведомляется об изменениях, которые он сделал сам, а о том, как было запрошено изменение, которое он запрашивал.

Если у вас действительно есть проблема с производительностью, что вы можете сделать, взломав шаблон наблюдателя другим способом

  • удалить TextEditor в качестве наблюдателя перед вызовом sendText и последующим чтением его
  • , если все вызовы синхронны: предотвращение автоматического обновления TextEditor путем установки атрибута
  • и т. Д.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...