Bagikan melalui


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

  1. 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 generik Temperature.

    public class TemperatureReporter : IObserver<Temperature>
    
    Public Class TemperatureReporter : Implements IObserver(Of Temperature)
    
  2. 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 metode Subscribe yang memanggil metode Subscribe penyedia dan menetapkan objek yang dikembalikan ke variabel unsubscriber.

    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
    
  3. 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
    
  4. 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

Lihat juga