Skip to content

Instantly share code, notes, and snippets.

@yetanotherchris
Last active December 12, 2015 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yetanotherchris/4746426 to your computer and use it in GitHub Desktop.
Save yetanotherchris/4746426 to your computer and use it in GitHub Desktop.
Observer design pattern example
namespace DesignPatterns
{
/// <summary>
/// The use of an interface here mightseem a bit redundent, but it's to keep
/// inline with the original gang of 4 definition of the pattern. The implementing class
/// is still responsible for wiring itself to the Subject's notify event.
/// </summary>
public interface IObserver
{
void Update(string message);
}
public class Observer : IObserver
{
/// <summary>
/// A friendly name for the Observer.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Filters messages starting with the string provided.
/// </summary>
public string MessageFilter { get; set; }
/// <summary>
/// Creates a new instance of an Observer.
/// </summary>
/// <param name="subject">The class that broadcasts/notifies us of its actions.</param>
/// <param name="name">A friendly name for the observer.</param>
public Observer(Subject subject, string name)
{
Name = name;
subject.Notify += new Action<string>(Update);
}
/// <summary>
/// Called each time the Subject notifies this Observer.
/// </summary>
/// <param name="message"></param>
private void Update(string message)
{
// Filter the message?
if (!string.IsNullOrEmpty(MessageFilter))
{
if (message.StartsWith(MessageFilter))
Console.WriteLine("{0} received the message {1}", Name, message);
}
else
{
Console.WriteLine("{0} received the message {1}", Name, message);
}
}
}
/// <summary>
/// This is the class that would perform all or any tasks and then inform
/// each subscribed Observer when it has down this.
/// </summary>
public class Subject
{
/// <summary>
/// Tradionalists might want this to use a delegate called *EventHandler
/// but I'm being lazy and using the Generic Action<T> delegate.
/// </summary>
public event Action<string> Notify;
public void Run()
{
Thread thread = new Thread(new ThreadStart(InternalRun));
thread.Start();
}
/// <summary>
/// A small mockup to simulate doing some work.
/// </summary>
private void InternalRun()
{
string message;
// 5 basic messages, sleeping between them to simulate
// intensive IO operations or calculations.
message = "Calculating Pi to 2000 dp.";
OnNotify(message);
Thread.Sleep(2000);
message = "Copying an item over the network using Vista pre-SP1";
OnNotify(message);
Thread.Sleep(2000);
message = "Finding all files that end in *.dll";
OnNotify(message);
Thread.Sleep(2000);
message = "Formatting a floppy.";
OnNotify(message);
Thread.Sleep(2000);
message = "Spidering google.";
OnNotify(message);
Thread.Sleep(2000);
}
/// <summary>
/// Send out a notification to all Observers.
/// </summary>
protected virtual void OnNotify(string message)
{
if (Notify != null)
Notify(message);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment