Cara: Menerapkan Pengamat
Pola desain pengamat memerlukan pembagian antara penyedia, yang mendaftar untuk pemberitahuan, serta penyedia, yang memantau dan mengirim pemberitahuan ke satu atau lebih pengamat. Topik ini membahas cara membuat pengamat. Topik terkait, Cara: Implementasi Penyedia, membahas cara membuat penyedia.
Untuk membuat pengamat
Tentukan pengamat, yaitu merupakan jenis yang mengimplementasikan antarmuka System.IObserver<T>. Misalnya, kode berikut menentukan jenis bernama
TemperatureReporter
yang merupakan implementasi System.IObserver<T> yang dibangun dengan argumen jenis generikTemperature
.public class TemperatureReporter : IObserver<Temperature>
Public Class TemperatureReporter : Implements IObserver(Of Temperature)
Jika pengamat dapat berhenti menerima pemberitahuan sebelum penyedia memanggil implementasi IObserver<T>.OnCompleted, tentukan variabel privat yang akan menahan implementasi IDisposable yang dikembalikan oleh metode IObservable<T>.Subscribe penyedia. Anda juga harus menentukan metode langganan yang memanggil metode Subscribe penyedia dan menyimpan objek IDisposable yang dikembalikan. Misalnya, kode berikut menentukan variabel privat bernama
unsubscriber
dan menentukan metodeSubscribe
yang memanggil metode Subscribe penyedia dan menetapkan objek yang dikembalikan ke variabelunsubscriber
.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
Tentukan metode yang memungkinkan pengamat berhenti menerima pemberitahuan sebelum penyedia memanggil implementasi IObserver<T>.OnCompleted, jika fitur ini diperlukan. Contoh berikut menentukan metode
Unsubscribe
.public virtual void Unsubscribe() { unsubscriber.Dispose(); }
Public Overridable Sub Unsubscribe() unsubscriber.Dispose() End Sub
Sediakan implementasi tiga metode yang ditentukan oleh antarmuka IObserver<T>: IObserver<T>.OnNext, IObserver<T>.OnError, dan IObserver<T>.OnCompleted. Tergantung pada penyedia dan kebutuhan aplikasi, metode OnError dan OnCompleted dapat menjadi implementasi stub. Perhatikan bahwa metode OnError tidak boleh menangani objek Exception yang diteruskan sebagai pengecualian, dan metode OnCompleted ini bebas untuk memanggil implementasi IDisposable.Dispose penyedia. Contoh berikut menunjukkan implementasi IObserver<T> dari kelas
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 {value.Degrees}°C at {value.Date:g}"); 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
Contoh
Contoh berikut berisi kode sumber lengkap untuk kelas TemperatureReporter
, yang menyediakan implementasi IObserver<T> bagi aplikasi pemantauan suhu.
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 {value.Degrees}°C at {value.Date:g}");
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