2012-04-03 3 views
4

При чтении статей по шаблону наблюдателя, я наткнулся ниже точки, перечисленной в обязательствах шаблона наблюдателяОбязательства наблюдателя: почему наблюдатель изменил свою тему?

объекты Observer полностью независимы, и они не имеют никакого знания о существовании коллег наблюдателей. Следовательно, объект объект Observer может изменить состояние объекта (в методе обновления) до того, как будут уведомлены даже все наблюдатели. Это может привести к несогласованности состояния, а уведомления об изменении состояния будут потеряны.

  1. Зачем менять тему? Разве не следует уведомлять наблюдателей об изменении предмета, а не изменять сам предмет?

В случае, если это возможно

  1. Pls дайте мне знать беспересадочный пример
  2. указать также, почему не субъект может ограничить себя от позволяет любому наблюдателю, чтобы изменить его, прежде чем ранее изменения уведомляется все наблюдатели?

ответ

3

Нигде не указано, что Наблюдатель сам не может изменить свой Предмет, хотя это не рекомендуется в большинстве случаев из-за вышеуказанных причин. Однако технически это возможно, особенно если вызов уведомления включает Субъект себя в качестве параметра:

class MyObserver implements Observer<MySubject> { 
    ... 
    public void notify(MySubject theSubject) { 
    ... 
    theSubject.changeSomeProperty(newValue); 
    } 
    ... 
} 

А как предотвратить наблюдатель от изменения объекта во время цикла уведомления происходит, я вижу несколько вариантов, но каждый из них вводит дополнительную сложность, ни одна из них не является гарантией на 100%, а некоторые из них более сложны, чем того стоит.

  • проход только для чтения только интерфейс Тема для наблюдателей - это самый простой в реализации, без каких-либо побочных эффектов, однако злой наблюдатель все еще может попытаться обратное приведение Тема для доступа к методам модификаторов, и/или доступ к полному предмету через какой-либо другой объект (-ы)
  • реализовать общественный объект как доступный только для чтения Адаптер к реальному предмету и опубликовать только первый - это предотвращает трюк с понижением и может затруднить его (но не невозможно) для Наблюдателей для доступа к реальному Субъекту через какой-либо другой объект (ы)
  • «заблокировать» тему на время обновления, установив, например, флаг, который проверяется в каждом методе модификатора (а затем, например, генерирует исключение, если флаг включен) - это предотвращает не только Наблюдателей, но и всех, кто может изменить объект в течение критического времени, что может быть или не быть желательным
1

Хотя это не рекомендуется, ничто не мешает наблюдателям изменять состояние наблюдаемого объекта (обычно, см. Const-correctness в C++ для контрпримера). Конечно, наблюдаемый объект может прыгать, хотя обручи, чтобы предотвратить/запретить это, но это утомительно.

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

1

Если наш вопрос S и у нас зарегистрировано двух наблюдателей; A и B, затем:

Если A «s responseHandler() содержит код, который будет изменять S, то это изменило бы состояние S до того B получает уведомление.

Код для обработки конкретного заказа или других специальных условий будет принадлежать в notifyObservers() методы S «s, где вы могли бы флаг S, как немодифицируемые или, возможно, подготовить некоторый конкретный порядок nottification для обновления S.

Смежные вопросы