.Net Observer Pattern изменяется. Когда это произошло и почему?

1

Я просто пытался объяснить шаблон Observer коллеге для использования в приложении С#. Я заметил, что это должно быть достаточно легко реализовать, просмотрев документацию MSDN. Однако я с удивлением обнаружил, что пример MSDN отличается от того, как меня научили шаблону Observer. Имейте в виду, я в основном использовал шаблон в Java, но у меня создалось впечатление, что реализация.Net была почти такой же.

Модель, которую я знаю, использует методы Notify, Subscribe и Unsubscribe. Эта новая реализация, описанная в MSDN, использует OnNext, OnCompleted, OnError и Subscribe. Тем не менее, я могу найти статьи всего несколько лет назад, объясняя версию Notify.

На первый взгляд эта новая версия кажется излишне запутанной, и она меня слегка смущает. С каких это пор эта реализация была реализована и почему она была реализована таким образом? Ват - это преимущества?

Теги:
observer-pattern

2 ответа

3

Имейте в виду, что интерфейсы.NET Observer тесно связаны с MS Reactive Extensions. Если вы хотите понять добавленную функциональность, предоставляемую OnError/OnCompleted, это, вероятно, лучшее место для исследований. Остальная часть шаблона в основном совпадает с:

  1. Подписаться по-прежнему просто Подписка.
  2. Отказ от подписки предназначен для реализации путем удаления контекста, возвращаемого подпиской.
  3. OnNext соответствует Notify.

Так что единственной новой функциональностью является OnError (предоставление параллельного канала сообщения об ошибках, позволяющего наблюдателю знать, что наблюдаемое ввело состояние ошибки) и OnCompleted (чтобы наблюдатель знал, что наблюдаемый не будет предоставлять больше сообщений. ) Вы можете выполнить это с подробностями в сообщении, чтобы указать эти переходы состояния, но наличие их испеченных имеет смысл, если вы думаете о наблюдаемом как своего рода канал сообщений, который может претерпеть изменения состояния, которые несколько ортогональны намерению сами сообщения.

1

Четыре интерфейса, на которые нужно обратить внимание, заключаются в следующем.

IEnumerable<T>
    IEnumerator<T> GetEnumerator()

IEnumerator<T>
    bool MoveNext()
    T Current { get; }
    void Dispose()

IObservable<T>
    IDisposable Subscribe(IObserver<T>)

IObserver<T>
    void OnNext(T)
    void OnError(Exception)
    void OnCompleted()

Интерфейсы IEnumerable<T> и IObservable<T> являются двойственными. То же самое касается IEnumerator<T> и IObserver<T>. Интерактивные интерфейсы, IEnumerable<T> и IEnumerator<T>, используют семантику pull для описания последовательности T s. Реактивные интерфейсы, IObservable<T> и IObserver<T>, используют push-семантику для описания последовательности T s.

Предположим, что у меня есть IEnumerator<T> именем e. Когда я вызываю e.MoveNext() а затем e.Current в случае успеха, я концептуально получаю одну из трех вещей:

  • e.MoveNext() возвращает true и я получаю T
  • e.MoveNext() выбрасывает Exception
  • e.MoveNext() возвращает false и у меня есть завершение

Обратите внимание, как они точно соответствуют IObserver<T> OnNext, OnError, OnCompleted. Разница заключается в том, что в случае IEnumerator<T> я IObserver<T> информацию, но в случае IObserver<T> я нажимаю информацию.

Когда я вызываю IEnumerator<T>.Dispose, последовательность T отменяется. Аналогично, когда я вызываю Dispose в IDisposable возвращаемом IObservable<T>.Subscribe, последовательность T отменяется.

Когда я вызываю IEnumerable<T>.GetEnumerator я вытаскиваю IEnumerator<T>. Когда я вызываю IObservable<T>.Subscribe я нажимаю IObserver<T>.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню