Wednesday, June 25, 2014

The Observer/Publish-Subscribe Pattern in C#

The Observer Pattern is most commonly known also as the Publish/Subscribe Pattern.

The definition of the Observer Pattern is as follows:

The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically (Head First Design Patterns-the observer pattern).

Below is the corresponding code in C# for the Observer pattern found in the Head First Design Patterns book:
 
void Main()
{
    WeatherData weatherData = new WeatherData();
 
            CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
 
            weatherData.setMeasurements(80F, 65F, 30.4F);
            weatherData.setMeasurements(82F, 70F, 29.2F);
            weatherData.setMeasurements(78F, 90F, 29.2F);
}
 
 public class CurrentConditionsDisplay: Observer, DisplayElement
    {
        private float temperature;
        private float humidity;
        private Subject weatherData;
 
        public CurrentConditionsDisplay(Subject weatherData)
        {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
 
        public void update(float temperature, float humidity, float pressure)
        {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
 
        public void display()
        {
            Console.WriteLine("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
        }
    }
    
public interface Observer
    {
        void update(float temp, float humidity, float pressure);
    }
 
    public interface DisplayElement
    {
        void display();
    }
 
public interface Subject
    {
        void registerObserver(Observer o);
        void removeObserver(Observer o);
 
        void notifyObservers();
    }
 
public class WeatherData: Subject
    {
        private ArrayList observers;
        private float temperature;
        private float humidity;
        private float pressure;
 
        public WeatherData()
        {
            observers = new ArrayList();
        }
 
 
        public void registerObserver(Observer o)
        {
            observers.Add(o);
        }
 
        public void removeObserver(Observer o)
        {
            int i = observers.IndexOf(o);
            if (i >= 0)
            {
                observers.RemoveAt(i);
            }//if
        }
 
        public void notifyObservers()
        {
            for (int i = 0; i < observers.Count; i++)
            {
                Observer observer = (Observer)observers[i];
                observer.update(temperature, humidity, pressure);
            }
        }
 
        public void setMeasurements(float temperature, float humidity, float pressure)
        {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            measurementsChanged();
        }
 
        private void measurementsChanged()
        {
            notifyObservers();
        }
    }


If you are looking to use .NET's built-in IObservable interface, you can read more about that here: http://msdn.microsoft.com/en-us/library/dd990377%28v=vs.110%29.aspx

For an example of the Observer Design Pattern based on implementing the IObservable interface, you can find that here: http://msdn.microsoft.com/en-us/library/ee850490%28v=vs.110%29.aspx

No comments:

Post a Comment