Home > Development > Observer Pattern

Observer Pattern


Definition: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ObserverExamples
{

    public interface IObserver<T>
    {
        void Update(T item);
    }

    public interface ISubject<T>
    {
        void Attach(IObserver<T> observer);
        void Remove(IObserver<T> observer);
        void NotifyAll(T data);
    }

    public abstract class BaseSubject<T> : ISubject<T>
    {

        protected List<IObserver<T>> observers = new List<IObserver<T>>();

        public virtual void Attach(IObserver<T> observer)
        {
            observers.Add(observer);
        }

        public virtual void Remove(IObserver<T> observer)
        {
            observers.Remove(observer);
        }

        public void NotifyAll(T data)
        {
            long count = observers.Count;
            long completed = 0;

            AutoResetEvent autoResetEvent = new AutoResetEvent(false);

            foreach (var observer in observers)
            {

                var t = observer;

                ThreadPool.QueueUserWorkItem(
                    x =>
                        {
                            try
                            {
                                t.Update(data);
                                Interlocked.Increment(ref completed);
                                if (Interlocked.Read(ref completed) == count)
                                {
                                    autoResetEvent.Set();
                                }
                            }catch
                            {
                                Interlocked.Increment(ref completed);
                                if (Interlocked.Read(ref completed) == count)
                                {
                                    autoResetEvent.Set();
                                }
                            }
                        }
                    );
            }

            autoResetEvent.WaitOne(TimeSpan.FromSeconds(50));
        }
    }

    public class ChannelData
    {
        public float Frequency { get; set; }
        public string StationName { get; set; }
    }

    public class RadioStation : BaseSubject<ChannelData>
    {
        private string _stationname;
        private float _frequency;


        public RadioStation(string stationname, float frequency)
        {
            _stationname = stationname;
            _frequency = frequency;
        }


        public string Stationname
        {
            get { return _stationname; }
        }

        public void ChangeFrequency(float freq)
        {
            _frequency = freq;
            NotifyAll(new ChannelData{ StationName = Stationname, Frequency = _frequency});
        }
    }

    public class PersonRadioListener : IObserver<ChannelData>
    {
        public void Update(ChannelData item)
        {
            Random r = new Random(57);
            Thread.Sleep(TimeSpan.FromSeconds(r.Next(6)));
            Console.WriteLine("Hey {0} is now on {1}",item.StationName,item.Frequency);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            PersonRadioListener blair = new PersonRadioListener();
            PersonRadioListener alep = new PersonRadioListener();

            RadioStation station = new RadioStation("Capitan FM",69.2F);
            station.Attach(blair);
            station.Attach(alep);

            station.ChangeFrequency(69.1F);

            Console.ReadKey();
        }
    }
}

Blair…

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: