관찰자 디자인 패턴에는 알림을 등록하는 관찰자와 데이터를 모니터링하고 하나 이상의 관찰자에게 알림을 보내는 공급자 간의 구분이 필요합니다. 이 항목에서는 관찰자를 만드는 방법에 대해 설명합니다. 관련 항목인 방법: 공급자구현에서는 공급자를 만드는 방법에 대해 설명합니다.
관찰자를 만들려면
System.IObserver<T> 인터페이스를 구현하는 형식인 관찰자를 정의합니다. 예를 들어 다음 코드는
TemperatureReporter제네릭 형식 인수를 사용하여 생성된 System.IObserver<T> 구현인Temperature형식을 정의합니다.public class TemperatureReporter : IObserver<Temperature>Public Class TemperatureReporter : Implements IObserver(Of Temperature)공급자가 IObserver<T>.OnCompleted 구현을 호출하기 전에 관찰자가 알림 수신을 중지할 수 있는 경우 공급자의 IDisposable 메서드에서 반환된 IObservable<T>.Subscribe 구현을 보유할 프라이빗 변수를 정의합니다. 또한 공급자의 Subscribe 메서드를 호출하고 반환된 IDisposable 개체를 저장하는 구독 메서드를 정의해야 합니다. 예를 들어 다음 코드는
unsubscriber프라이빗 변수를 정의하고 공급자의Subscribe메서드를 호출하고 반환된 개체를 Subscribe 변수에 할당하는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이 기능이 필요한 경우 공급자가 IObserver<T>.OnCompleted 구현을 호출하기 전에 관찰자가 알림 수신을 중지할 수 있도록 하는 메서드를 정의합니다. 다음 예제에서는
Unsubscribe메서드를 정의합니다.public virtual void Unsubscribe() { unsubscriber.Dispose(); }Public Overridable Sub Unsubscribe() unsubscriber.Dispose() End SubIObserver<T> 인터페이스에서 정의한 세 가지 메서드인 IObserver<T>.OnNext, IObserver<T>.OnError및 IObserver<T>.OnCompleted구현을 제공합니다. 공급자 및 애플리케이션의 요구 사항에 따라 OnError 및 OnCompleted 메서드는 스텁 구현일 수 있습니다. OnError 메서드는 전달된 Exception 개체를 예외로 처리해서는 안 되며 OnCompleted 메서드는 공급자의 IDisposable.Dispose 구현을 자유롭게 호출할 수 있습니다. 다음 예제에서는 IObserver<T> 클래스의
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: {value.Degrees - last.Degrees}° in {value.Date.ToUniversalTime() - last.Date.ToUniversalTime():g}"); } }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
예시
다음 예제에서는 온도 모니터링 애플리케이션에 대 한 TemperatureReporter 구현을 제공 하는 IObserver<T> 클래스에 대 한 전체 소스 코드를 포함 합니다.
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: {value.Degrees - last.Degrees}° in {value.Date.ToUniversalTime() - last.Date.ToUniversalTime():g}");
}
}
}
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
참고하십시오
.NET