Wednesday, October 18, 2017

Observer Design Pattern

Alright lets discuss about one of the Behavioral Pattern - Observer Pattern.

Lets understand where we should use this pattern.

Which problem does this Pattern solve.?
Ans. To understand the pattern we need to understand the problem. This pattern is associated with Publisher and Subscriber model.

Poll Architecture : In this type of architecture the subscriber(s) will continously look  for publisher changes.

The disadvantage with this type of architecture.

1.Even if the Publisher has made no changes the subsciber(s) will continously check to see if there are any changes.

2.The subscriber(s) would have to set a time frame. For example after every 5 min check to see if there are any publisher changes. there could be a publisher change at the 6th min.

3.There could be possible network overhead.

So this Pattern introduces a new type of architecture that is Push Architecture.

Push Architecture - In this type architecture the publisher will tell what is changed and notify the subscriber(s)

The Advantage with this type of architeture.

1.There would be no network overhead.

2.The Subscriber(s) don't have to keep looking for the Publisher changes.

3.There would be no time lapses as publisher will intimate all the subsciber(s)

Definition

Define one to many dependencies/relationships between objects so that when one object changes state then all its dependents are updated/notified automatically.

So lets jump into Weather Station example. This is a hypothetical example.

So we should have a Observable which we define it as Publisher who will notify all the Observers which we define it as Subscriber(s)

Lets create an Observable.It should have - 3 methods  - Attach (Observer) - Detach(Observer) - Notify() to the observers.

Lets create an interface for the same.

public interface IObservable
{
        void Attach(IObserver observer);
        void Detach(IObserver observer);
        void Notify();
}

Attach(Observer) - We need to attach all the observer(s)/subscriber(s) so that the observable/publisher knows to notify its subscibers.

Detach(Observer)  - We can detach the subsciber(s) if not required.

Notify()  - This method is used to notify all the subscribers that there is some changes in the publisher

So in the above we have created a Publisher interface which must and should have these methods.

Lets now create an Observer/Subscriber.

public interface IObserver
{
        void Update();
}

Update() - When the publisher calls Notify Method- It will internally call the update method of each subscribers that will notify the changes to their view.

So lets create  conrete class for the Observable/Publisher - Here we are taking WeatherStation as Publisher.

public class WeatherStation : IObservable
{
        readonly List<IObserver> _observers = new List<IObserver>();
        public int Temperature { get; set; }

        public void Attach(IObserver observer)
        {
            _observers.Add(observer);
        }

        public void Detach(IObserver observer)
        {
            _observers.Remove(observer);
        }

        public void Notify()
        {
            foreach (var observer in _observers)
            {
                observer.Update();
            }
        }

        public int GetTemperature()
        {
            return Temperature;
        }
 }

In the above code you can see we have implemented all the methods in the IObservable and also we have put a new method GetTemperature() - we have implemented this to tell the subscribers that there was a change in  temperature and we notify the subscibers about the same.

So lets create  conrete class for the Observer/Subscriber - Here we are taking PhoneDisplay and ComputerDisplay as subscibers(s). Just an Example(Don't know if they make sense :P)

So lets implement them.

 public class PhoneDisplay : IObserver
 {
        private readonly WeatherStation _weatherStation;
        public PhoneDisplay(WeatherStation weatherStation)
        {
            _weatherStation = weatherStation;
        }

        public void Update()
        {
            Console.WriteLine("Phone Display Temperature"+_weatherStation.GetTemperature());
        }
 }

public class ComputerDisplay : IObserver
{
        private readonly WeatherStation _weatherStation;

        public ComputerDisplay(WeatherStation weatherStation)
        {
            _weatherStation = weatherStation;
        }

        public void Update()
        {
            Console.WriteLine("Computer Display Temperature"+_weatherStation.GetTemperature());
        }
 }

In the above code you could see that there is a concrete class constructor which has a  WeatherStation reference we need this reference so that Subscriber knows to which Publisher it has got attached or referenced to. And also we use the methods of the WeatherStation to notify the changes to subsciber view.

So in the above implementation we see that in the Update method we are using  _weatherStation.GetTemperature() to notify the view about the changes to the temperature.

The Notify method in the weather station is the heart of this pattern.
public void Notify()
{
            foreach (var observer in _observers)
            {
                observer.Update();
            }
}

The notify methods iterate through each observer(s)/subscriber(s) and will notify the user that there is some changes to its state.

Lets see how we attach and notify asubscibers.

class Program
    {
        static void Main(string[] args)
        {
            WeatherStation station = new WeatherStation();
            station.Attach(new ComputerDisplay(station));
            station.Attach(new PhoneDisplay(station));

            station.Temperature = 23;
            station.Notify();

            Console.WriteLine("--------------------------------------------------------");

            station.Temperature = 66;
            station.Notify();
            Console.ReadLine();
        }
   }

In the above code. We are creating an instance of the weatherstation and attaching the subsciber(s) with weather station reference in it. We change the temperature and notify all the subscriber(s)

Happy Coding :) :) :)


No comments:

Post a Comment