Procedimiento para implementar un observador
El modelo de diseño de observador requiere una división entre un observador, que registra notificaciones, y un proveedor, que controla los datos y envía notificaciones a uno o varios observadores. En este tema se describe cómo crear un observador. En un tema relacionado, Cómo implementar un proveedor, se describe cómo crear un proveedor.
Para crear un observador
Defina el observador, que es un tipo que implementa la interfaz System.IObserver<T>. Por ejemplo, el código siguiente define un tipo llamado
TemperatureReporter
, que es una implementación System.IObserver<T> construida con un argumento de tipo genérico deTemperature
.public class TemperatureReporter : IObserver<Temperature>
Public Class TemperatureReporter : Implements IObserver(Of Temperature)
Si el observador puede dejar de recibir notificaciones antes de que el proveedor llame a su implementación IObserver<T>.OnCompleted, defina una variable privada que contenga la implementación IDisposable devuelta por el método IObservable<T>.Subscribe del proveedor. También debe definir un método de suscripción que llame al método Subscribe del proveedor y almacene el objeto IDisposable devuelto. Por ejemplo, el código siguiente define una variable privada denominada
unsubscriber
y define un métodoSubscribe
que llama al método Subscribe del proveedor y asigna el objeto devuelto a la variableunsubscriber
.public class TemperatureReporter : IObserver<Temperature> { private IDisposable unsubscriber; private bool first = true; private Temperature last; public virtual void Subscribe(IObservable<Temperature> provider) { unsubscriber = provider.Subscribe(this); }
Public Class TemperatureReporter : Implements IObserver(Of Temperature) Private unsubscriber As IDisposable Private first As Boolean = True Private last As Temperature Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Temperature)) unsubscriber = provider.Subscribe(Me) End Sub
Defina un método que permita al observador dejar de recibir notificaciones antes de que el proveedor llame a su implementación IObserver<T>.OnCompleted, en caso de que esta característica sea necesaria. En el ejemplo siguiente, se define un método
Unsubscribe
.public virtual void Unsubscribe() { unsubscriber.Dispose(); }
Public Overridable Sub Unsubscribe() unsubscriber.Dispose() End Sub
Proporcione implementaciones de los tres métodos definidos en la interfaz IObserver<T>: IObserver<T>.OnNext, IObserver<T>.OnError y IObserver<T>.OnCompleted. En función del proveedor y de las necesidades de la aplicación, los métodos OnError y OnCompleted pueden ser implementaciones de código auxiliar. Tenga en cuenta que el método OnError no debe controlar el objeto Exception pasado como una excepción y que el método OnCompleted es libre de llamar a la implementación IDisposable.Dispose del proveedor. El siguiente ejemplo muestra la implementación IObserver<T> de la clase
TemperatureReporter
.public virtual void OnCompleted() { Console.WriteLine("Additional temperature data will not be transmitted."); } public virtual void OnError(Exception error) { // Do nothing. } public virtual void OnNext(Temperature value) { Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date); if (first) { last = value; first = false; } else { Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees, value.Date.ToUniversalTime() - last.Date.ToUniversalTime()); } }
Public Overridable Sub OnCompleted() Implements System.IObserver(Of Temperature).OnCompleted Console.WriteLine("Additional temperature data will not be transmitted.") End Sub Public Overridable Sub OnError(ByVal [error] As System.Exception) Implements System.IObserver(Of Temperature).OnError ' Do nothing. End Sub Public Overridable Sub OnNext(ByVal value As Temperature) Implements System.IObserver(Of Temperature).OnNext Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date) If first Then last = value first = False Else Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees, value.Date.ToUniversalTime - last.Date.ToUniversalTime) End If End Sub
Ejemplo
El siguiente ejemplo contiene el código fuente completo para la clase TemperatureReporter
, que ofrece la implementación IObserver<T> de una aplicación de supervisión de temperatura.
public class TemperatureReporter : IObserver<Temperature>
{
private IDisposable unsubscriber;
private bool first = true;
private Temperature last;
public virtual void Subscribe(IObservable<Temperature> provider)
{
unsubscriber = provider.Subscribe(this);
}
public virtual void Unsubscribe()
{
unsubscriber.Dispose();
}
public virtual void OnCompleted()
{
Console.WriteLine("Additional temperature data will not be transmitted.");
}
public virtual void OnError(Exception error)
{
// Do nothing.
}
public virtual void OnNext(Temperature value)
{
Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date);
if (first)
{
last = value;
first = false;
}
else
{
Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees,
value.Date.ToUniversalTime() - last.Date.ToUniversalTime());
}
}
}
Public Class TemperatureReporter : Implements IObserver(Of Temperature)
Private unsubscriber As IDisposable
Private first As Boolean = True
Private last As Temperature
Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Temperature))
unsubscriber = provider.Subscribe(Me)
End Sub
Public Overridable Sub Unsubscribe()
unsubscriber.Dispose()
End Sub
Public Overridable Sub OnCompleted() Implements System.IObserver(Of Temperature).OnCompleted
Console.WriteLine("Additional temperature data will not be transmitted.")
End Sub
Public Overridable Sub OnError(ByVal [error] As System.Exception) Implements System.IObserver(Of Temperature).OnError
' Do nothing.
End Sub
Public Overridable Sub OnNext(ByVal value As Temperature) Implements System.IObserver(Of Temperature).OnNext
Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date)
If first Then
last = value
first = False
Else
Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees,
value.Date.ToUniversalTime - last.Date.ToUniversalTime)
End If
End Sub
End Class