Когда и кто должен отсоединять наблюдателей, когда наблюдатель имеет более продолжительный срок службы, чем наблюдаемый - PullRequest
4 голосов
/ 23 сентября 2011

Я столкнулся с этой проблемой, используя стороннюю библиотеку, предоставленную другой группой в компании (написано на C ++).

В деструкторе Observer он отделяется от всех наблюдаемых, на которые он подписывается, эта часть имеет смысл для меня. Но в деструкторе Observable он проверяет, есть ли у наблюдаемого наблюдателя, который все еще находится в его списке подписчиков. Если это так, выдает ошибку.

Я собираюсь отложить тот факт, что он намеренно отбрасывает ошибку в деструкторе в сторону. Может ли кто-нибудь попытаться объяснить мне, почему наблюдаемое не должно ожидать, что наблюдатели переживут себя, или это просто плохая схема. Если это плохой дизайн, когда мы находимся в обстоятельствах, когда наблюдатель переживает наблюдаемое, есть ли хорошие способы справиться с этим?

Ответы [ 4 ]

6 голосов
/ 23 сентября 2011

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

Думаю, есть три обычных решения.

Один из них заключается в том, чтобы делать именно то, что делает этот код, возможно, вызывая abort (), а не вызывать исключение в деструкторе.

Другой способ состоит в том, чтобы деструктор Observable отменил регистрацию у любых наблюдателей.

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

0 голосов
/ 24 сентября 2011

Это просто плохой дизайн, ничто не гарантирует, что наблюдаемая переживет всех своих наблюдателей.

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

0 голосов
/ 23 сентября 2011

Я обычно реализовывал шаблон наоборот: Observable добавляет себя и удаляет из списка Observer.Мой наблюдатель живет в течение всего срока службы приложения, а наблюдаемые обычно живут несколько секунд.

0 голосов
/ 23 сентября 2011

Это зависит от контекста. Я ожидал бы совершенно общего реализация шаблона наблюдателя для поддержки удаления наблюдаемого объект, по крайней мере, необязательно, но есть много применений, где это не имеет смысла и, вероятно, является ошибкой программирования. В общем, прежде чем наблюдаемое полностью разрушит, оно должно уведомить своих наблюдателей тот факт, что он будет разрушать; они должны тогда unenrol. Что значит что к тому времени деструктор наблюдаемого объекта реестра не должно быть зарегистрированных наблюдателей.

...