Skip to content
October 22, 2008 / Shrikant Patil

Behavioral Design Patterns: Observer Design Pattern

The second pattern of Behavioral Design Patterns group is Observer Design Pattern. The pattern contains central point (Subject) to which information gathering Objects (Observers) get subscribed to get information on state change in central Point (Subject). Simply we can say that this like subscribed information distribution.
Suppose say you have subscribed for a newsletter of any web site. Then the website behaves as Information Center (Subject) and your email service as Information gathering (Observer) object. If any new news published form the Information center (subject) you receive it through mail because you are Observer in this model. And if you don’t want to receive any newsletter then you (Observer) can unsubscribe yourself from the Information Center (Subject), so you will not receive any newsletter form the information center (subject).

The information center (Subject) provides methods to subscribe for newsletter service and unsubscribe method to unsubscribe from the newsletter service for subscribers (Observers). The information Center keeps a list of all subscribers (Observers) and when any newsletter is published form the Information Center (Subject) then Information Center (Subject) loop through the list all subscribers and call a method (in our case it holds email ids of subscribers) on Subscribers (Observers) and pass the latest newsletter to the Subscribers (Observers). This is what overall idea behind the Observer Pattern.

Coming to application development, Say there is single source of information which broadcast the data to subscribing objects. We know that it is better to have a single source of data point than having more than of one. So any change in state of Central point (subject) is broadcasted to all subscribing instances. The relation between the Observers and Subject is one-to-many relation which is loosely coupled.

From the above figure, The Pattern consists two main points, The Subject and Observers. Subject is central part of the information for Observers. If any update or change in the information in Subject will reflect on each subscribing Observer. Subject provides AddObserver () method so that a new Observer can subscribe itself to the Subject. Once it is subscribed, Subject keeps it in its subscriber list. Each Observer provides an Update () method which can be get called by subject to pass latest data to the observer. At any time state or data of the Subject changed then subject loop through its subscribed Observers and pass the latest data to subscribed observers by calling an Update () method on each Observer.

The Subject also provides a method for unsubscribing, which is used by subscribed Observer to unsubscribe itself to receive the data form the Subject. If any Subscribed Observer unsubscribe  itself by calling RemoveObserver() method on Subject, then Subject again loop through the list subscribed Observers and remove the instance of Observer, so unsubscribed Observer not receives any data form Subject in future. Any number of Observers can subscribe to subject to receive the data. The Subject delegates the operations to Observer, so the pattern uses composition instead of inheritance.
Let us get bigger picture by looking at the UML diagram;

Here is theoretical definition of Observer pattern;
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. Subject uses composition to delegate the observer.

In observer pattern, subject defines one-to-many relationship with Observers. Observers are totally dependent on the Subject. At any point if state of subject changed, the observers are get notified and observers will receive updated data.
As we see in the UML diagram, both concrete subject and concrete observer implements subject and observer interface. Let us look in each class;

Subject Interface:
This interface defines the signature of methods which are implemented in concrete subject object. The methods are used by the observers to register and unregister from being observers.  Interface also defines a signature of method which is used to notify the observers when status of subject is changed.

Observer Interface:
This interface defines the signatures of methods which implemented in concrete Observer objects. The interface at least define signature of one method which is get called by subject when its state changes.

Concrete Subject:
Concrete Subject implements the Subject Interface. Concrete subject declare an array to hold references of instances of all registered concrete observer instances. The class defines the implementation of methods from Subject Interface and may some additional methods;
AddObserver(observer) – which is used by concrete observer object to register itself with Subject by passing itself as parameter. The method loop through an array which holds all instances of registered observers, to check weather the registering instance already present in the array. If it is not present then only the requesting new instance of concrete observer is added to the array.
RemoveObserver(observer) – Which is used by concrete observer to unregister itself from subject passing itself as parameter. The method loop through an array which holds all instances of registered observers, to check weather the requesting instance already present in the array. If it is present then only the requesting instance of concrete observer is removed from the array.
NotifyObservers() –  which is used to update the concrete observers on state change of subject. The method loop through an array which holds all instances of registered observers and call update() method on each concrete observer object, if required we can pass some values related to state change of subject through the update() method on observer objects.

The concrete Subject also may define the methods like getState() and setState(), which are used to set and get the state change of application on Subject, so that it can update the state change to all registered observers.

Concrete Observer:
Concrete Observer implements Observer interface. The class implement the update () method whose signature defined in Observer interface. This method of concrete Observer gets called by Subject (if this concrete Observer already is registered itself with subject) when any change in its state.

Let us do some sample application coding, so that we will get bright idea of the pattern. Here I have created a simple example. Subject can be set with a color value. On changing the color value on subject will notify all of its observers passing that color value to all observers. Observers simple have a canvas with default white color. When observers get notified with new color value from subject each observer applies that new color value to the canvas.

Creating Subject Interface:
Interface defines signatures for AddObserver(), RemoveOnbserver() and NotifyObserver() methods;

package flexScript
{
    public interface Subject
    {
        function AddObserver(obs:Observers):void;
        function RemoveObserver(Obs:Observers):void;
        function NotifyObservers():void;

    }
}

Creating Observers Interface:
Interface defines at least Update () method signature.

package flexScript
{
    public interface Observers
    {
        function update(colr:uint):void;
    }
}

Creating concrete Subject:
In our Application the name of Concrete Subject is ColorSubject. (Look into the comments in the code. Comments explain everything about the class).

package flexScript
{   
    //Comcrete Subject implements Subject interface
    public class ColorSubject implements Subject
    {
        //define an array to hold references of all observer instances
        private var observerList:Array;
        private var currentColor:uint;
        public function ColorSubject()
        {
            //initilize array
            observerList = new Array();
        }
        //implement the AddObserver method so that Observer can register
        //itself to Subejct by calling this method
        public function AddObserver(obs:Observers):void
        {
            var isSame:Boolean = false;
            //add the new observer instane to array
            //new observer is registered with subejct
            for(var k:int=0;k<observerList.length;k++){
                //check weather this instance is already registered
                if(observerList&#91;k&#93; == obs){
                    isSame = true;
                }
            }
            //if this instance is not registere before then add it to list
            if(!isSame){
                observerList.push(obs);
            }
        }
        //implement RemoveObserver so that an Observer can unregister
        //themself from the subject by calling this method
        public function RemoveObserver(Obs:Observers):void
        {
            //loop through the array and find the instance of observer
            //to remove it form the list
            for(var i:int=0; i<observerList.length;i++){
                if(observerList&#91;i&#93; == Obs){
                    //if instane found on list, remove that instance from list
                    observerList.splice(i,1);
                    break;
                }
            }
        }
        //implement NotifyObservers method which is used to notify all
        //registered observers when new color value updated
        public function NotifyObservers():void
        {
            //loop through all registered instances of observers
            //and call Update() method of each observer and pass new
            //color value
            for (var j:int=0; j<observerList.length; j++){
                observerList&#91;j&#93;.update(currentColor);
            }
        }
        //this is additional method used to set new color value on subject
        public function setColor(colr:uint):void{
            currentColor = colr;
            //once new color value updated call NotifyObservers() method
            //so that each observer get the new color value
            NotifyObservers();
        }
    }
}

&#91;/sourcecode&#93;

<strong>Creating Observers :</strong>
In our application I am going to create two Observers.
<em>Observer1</em> - Extends Canvas class, it changes the background color of canvas when update () method is called and new color value is passed from the Subject.<em>
Observer2 </em>- Extends Text. It changes the font color of default text when update () method is called and new color value is passed form the subject.


package flexScript
{
    import mx.containers.Canvas;
    //concrete observer must implement Observer interface
    public class Observer1 extends Canvas implements Observers
    {
        private var currentColor:uint;
        public function Observer1()
        {
            super();
            //set initial color of the canvas background
            setStyle("backgroundColor", currentColor);
        }
        //implement update() method. this method is get called by Subject
        //when Subject is get updated with new color value.
        public function update(colr:uint):void
        {    trace("aa"+colr);
            currentColor = colr;
            //update the color of canvas background
            this.setStyle("backgroundColor", currentColor);
        }

    }
}

package flexScript
{
    import mx.controls.Text;
    //concrete observer must implement Observer interface
    public class Observer2 extends Text implements Observers
    {
        private var currentColor:uint = 0xffffff;
        public function Observer2()
        {
            super();
            this.text = "This is Second Observer. You can change the color of font";
            //set initial color of font
            this.setStyle("fontColor",currentColor);
        }
        //implement update() method. this method is get called by Subject
        //when Subject is get updated with new color value.
        public function update(colr:uint):void
        { 
            currentColor = colr;
            //update the color of font
            this.setStyle("color",currentColor);
        }

    }
}

Creating Client:
I am using MXML file as client. it displays a color picker component to choose different colors. It also displays both observer1 and observer 2 components along with ‘Register’ and ‘unRegister’ buttons, so that you can register and unregister any of component at any time. Play with application you can understand the observer patter completely.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" xmlns:obs="flexScript.*"
creationComplete="init();"
height="216" width="458">
<mx:Script>
<!&#91;CDATA&#91;
    import mx.events.ColorPickerEvent;
    import flexScript.*;

    //create an instance of concrete Subject
    private var concreteSbject:ColorSubject;
    private var obs1:Observers;
    private var obs2:Observers;

    private function init():void{
    //initilize Subject and Observers
     concreteSbject = new ColorSubject();
     obs1 = ob1;
     obs2 = ob2;
    }

    //this method is get called when new color selected
    private function updateColor(e:ColorPickerEvent):void{
        //set new color value on Subject (you are changing its state)
        concreteSbject.setColor(e.color);
    }
    //this method register the target observer
    private function rgisterObserver(ob:Observers):void{
        //send the target observer to AddObserver method of subject
        concreteSbject.AddObserver(ob);
    }
    //this method unregisters the target observer
    private function unRgisterObserver(ob:Observers):void{
        //send the target observer to RemoveObserver method of subject
        concreteSbject.RemoveObserver(ob);
    }
&#93;&#93;>
</mx:Script>
    <mx:Label x="71" y="12" text="Choose New Color"/>
    <mx:ColorPicker x="181" y="10" id="colrPick" change="updateColor(event);"/>
    <obs:Observer1 x="35" y="77" width="118" height="69" id="ob1"/>
    <obs:Observer2 x="181" y="77" width="124" height="69" id="ob2"/>
    <mx:Label x="35" y="51" text="Observer 1"/>
    <mx:Label x="181" y="51" text="Observer 2"/>
    <mx:Button x="35" y="146" label="Register" click="rgisterObserver(ob1);"
    width="118" cornerRadius="0"/>
    <mx:Button x="35" y="168" label="UnRegister" click="unRgisterObserver(ob1);"
    width="118" cornerRadius="0"/>
    <mx:Button x="181" y="146" label="Register" width="124"
    click="rgisterObserver(ob2)" cornerRadius="0"/>
    <mx:Button x="181" y="168" label="UnRegister" width="124"
    click="unRgisterObserver(ob2)" cornerRadius="0"/>
</mx:Application>

Advertisements

2 Comments

Leave a Comment
  1. sharath / Dec 7 2008 2:11 am

    Hello,

    I have a default form with some fields, i want to give a option to customize that form so that he can add remove any thing to that form. What is the idea to maintain this kind of scenario ? Can we use Observer design pattern?

    Thanks

Trackbacks

  1. Observer Design Pattern – Usage and Example in PHP

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: