Skip to content

Instantly share code, notes, and snippets.

@dbuksbaum
Created May 2, 2015 17:42
Show Gist options
  • Save dbuksbaum/ab2d3049671657661271 to your computer and use it in GitHub Desktop.
Save dbuksbaum/ab2d3049671657661271 to your computer and use it in GitHub Desktop.
Patterns 101 – Observer Pattern
class ObserverTest
{
public void RunTest()
{
var observerable = new TheObservable();
var observer = new TheObserver();
using (observerable.Subscribe(observer))
{
// do something to change the state of an observable
}
}
}
class ObserverTestWithEvents
{
public event EventHandler DataChanged;
public void ChangeTheData()
{
if(DataChanged != null)
DataChanged(this, new EventArgs());
}
public static void HandleDataChanged(object sender, EventArgs args)
{
// do somthing magical here
}
public static void TestEvents()
{ // create our object
var myObject = new ObserverTestWithEvents();
// register event handler
myObject.DataChanged += HandleDataChanged;
try
{ // fire the event
myObject.ChangeTheData();
}
finally
{ // unregister event handler
myObject.DataChanged -= HandleDataChanged;
}
}
}
class TheObservable : IObservable<string>
{
class ObserverUnsubscriber : IDisposable
{
private readonly IList<IObserver<string>> _observers;
private readonly IObserver<string> _observer;
public ObserverUnsubscriber(IList<IObserver<string>> observers, IObserver<string> observer)
{
this._observers = observers;
this._observer = observer;
}
#region Implementation of IDisposable
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <filterpriority>2</filterpriority>
public void Dispose()
{
if ((_observer != null) && (!_observers.Contains(_observer)))
_observers.Remove(_observer);
}
#endregion
}
private readonly IList<IObserver<string>> _observers = new List<IObserver<string>>();
#region Implementation of IObservable<out string>
/// <summary>
/// Notifies the provider that an observer is to receive notifications.
/// </summary>
/// <returns>
/// The observer's interface that enables resources to be disposed.
/// </returns>
/// <param name="observer">The object that is to receive notifications.</param>
public IDisposable Subscribe(IObserver<string> observer)
{
if (!_observers.Contains(observer))
_observers.Add(observer);
return new ObserverUnsubscriber(_observers, observer);
}
#endregion
}
class TheObserver : IObserver<string>
{
#region Implementation of IObserver<in string>
/// <summary>
/// Provides the observer with new data.
/// </summary>
/// <param name="value">The current notification information.</param>
public void OnNext(string value)
{
// do something with the next value
}
/// <summary>
/// Notifies the observer that the provider has experienced an error condition.
/// </summary>
/// <param name="error">An object that provides additional information about the error.</param>
public void OnError(Exception error)
{
// uhoh! an error
}
/// <summary>
/// Notifies the observer that the provider has finished sending push-based notifications.
/// </summary>
public void OnCompleted()
{
// we are done
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment