65.9K
CodeProject is changing. Read more.
Home

The Observer Pattern

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (2 votes)

Feb 19, 2013

CPOL
viewsIcon

10267

downloadIcon

215

The "Observer Pattern" defines a One-To-Many dependency between objects.

Introduction

The "Observer Pattern" defines a One-To-Many dependency between objects.

when one object changes state, all of its dependentsare notified and updated automatically.


ONE Subject to the MANY Observers !!!!
Subject can be anything which interests Observers.
Observers are objects who are interested in some Subject.

EXAMPLE : Newpaper Subscription where "Newspaper is Subject" and "Subscribers are Observers".
          ONE Newspaper to MANY Subscribers.

Background

Design Principal  : Strive for loosely coupled designs between objects that interact.

Loosely coupled designs allow us to build flexible system that can handle changes becoz they minimize interdependency.


Note : Observer Pattern can be implemented using Events & Delegates in .Net, .Net 4.0 has now IObservable & IObserver interfaces to facilitate the Observer Pattern.
This Example has implementations using Custom Interface & .Net in-house IObservable interface.

Using the code

// Custom IObserver Interface

    public interface IObserver
    {
        void Update(float temp, float hum, float press);
    }

 // Observer Class which Observes or Subscribe from Observable Data

    public class CurrentConditionsDisplay : IObserver,IDisplayElement
    {
        private float temperature;
        private float humidity;
        private ISubject weatherData;

        public CurrentConditionsDisplay(ISubject weatherData)
        {
            this.weatherData = weatherData;
            if(weatherData != null)
                weatherData.RegisterObserver(this);
        }

        public void RemoveObservation()
        {
            weatherData.RemoveObserver(this);
        }

        public void Update(float temp, float hum, float press)
        {
            this.temperature = temp;
            this.humidity = hum;
            Display();
        }

        public void Display()
        {
            Console.WriteLine("Current Conditions: " + temperature + "F Degrees and " + humidity + "% Humidity");
        }
    }

 

// Custom IObservable Interface

    public interface ISubject
    {
        void RegisterObserver(IObserver observer);
        void RemoveObserver(IObserver observer);
        void NotifyObservers();
    } 

 

// Observable class which can be observed by Observer Class

    public class WeatherData : ISubject
    {
        private ArrayList Observers;
        private float _temperature;
        private float _humidity;
        private float _pressure;

        public WeatherData()
        {
            Observers = new ArrayList();
        }

        #region ISubject Members

        public void RegisterObserver(IObserver observer)
        {
            Observers.Add(observer);
        }

        public void RemoveObserver(IObserver observer)
        {
            int i = Observers.IndexOf(observer);
            if (i >= 0)
            {
                Observers.Remove(observer);
            }
        }

        public void NotifyObservers()
        {
            foreach (IObserver o in Observers)
            {
                o.Update(_temperature, _humidity, _pressure);
            }
        }

        #endregion

        public void MeasurementChanged()
        {
            NotifyObservers();
        }

        public void SetMeasurements(float temperature, float humidity, float pressure)
        {
            this._temperature = temperature;
            this._humidity = humidity;
            this._pressure = pressure;
            MeasurementChanged();
        }
    }

Points of Interest

This Pattern can be implemented by directly using IObserver<T> & IObservable<T> provided by .Net Library also, attached code includes implementation with .Net in-house interface as well.

History

Version 1