Reader Level:
ARTICLE

Implementation and Use of the Observer & ChainOfResonsibility Design Patterns

Posted by Ashish Shukla Articles | Design & Architecture May 05, 2012
In this article we will discuss the use and implementation of two of the most commonly used behavioral design patterns; the observer pattern and the ChainOfResonsibility pattern.
  • 0
  • 0
  • 3474


In this article we will discuss the use and implementation of two of the most commonly used behavioral design patterns; the observer pattern and the ChainOfResonsibility pattern.
The Observer Design pattern is officially defined as "Define a one to many dependency between objects such that when object changes state all its dependents are notified and updated automatically".

First we need to understand the need for this pattern using the following example:
You are working on the data access component that fetches and updates the data in the database.
Your Data Access Component would be used by different applications. Your problem is that since multiple applications will be using your component, it is possible that one application updates the data and the other applications continue to display the old data. You feel stuck between applications. This problem can be solved easily using the observer pattern. Your database component is the subject here that notifies the different applications whenever there is some change in its state.

img2.jpg

The Subject registers several observers and notifies the observers about the change.

We start by defining the Subject Interface which provides methods that our Data Access Component should implement since it is the subject here.

 

public interface Subject

    {

        //adds a new observer

        void registerObserver(Observer o);

        //removes an existing observer

        void removeObserver(Observer o);

        //notifies observers when there is a change in state

        void notifyObservers(string tablename, string column, string val);

    }

 

To enable our different applications to be notified of changes, our applications needs to implement the following observer interface since the applications here are observers of the data access component that wants to be notified of changes.

 

    public interface Observer

    {

         void update(string table, string val,string column);

    }

 

In the notifyObservers() we call the update() method to notify the observers (applications) of changes in the subject (data access component).

 

      public void notifyObservers(string tablename, string column, string val)

        {

            foreach (Observer observer in observers)

            {

                observer.update(tablename, val, column);

            }

        }

 

Now when our DataAccess component modifies the database using the following code all the observers (applications) are automatically notified of the database modifications so all the applications are synchronized.

 

dataAccess.ModifyDatabase("New Value1", "Test Table", "Test Column1");

 

The attached source code contains the implementation of the Observer pattern that you can customize according to the requirement.

 

Chain Of Responsibility

 

The next pattern we are going to discuss is Chain Of Responsibility pattern that also sends notifications to a number of objects. This pattern is about connecting the objects in a chain and passing the request along this chain so that the request is handled by the first object that can handle a request.

 

img3.jpg

 

Pass request along a chain of objects

 

Note that in the above diagram

  1. If the the Object1 handles the request then the request is not passed to the Object2.

  2. If the Object2  handles the request then the request is not passed to the Object3.

The Chain Of Responsibility is officially defined as "Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it."

 

The need of Chain Of Responsibility

 

You have done all the hard work and created a nice application that also performs well. Now the only thing that could make your application self describing to the users is the help functionality. It is using the help that users know how to use your application. So your help should be as specific as possible.

 

So The Chain Of Responsibility is the pattern you can use in this scenario. You can define help information for UI elements and the UI element should display that information if it is available or use the help information of its parent if it doesn't have it available.  In this example we take the case of the help system for the employees of an organization. We display the information for the employee which should be as specific as possible.

 

Our requirement is as below

  1. If the help based on the designation of the employee is available we display it.

  2. If the help based on the SubDepartment of the employee is available we display it.

  3. If the help based on the Department of the employee is available we display it.

  4. If no other help is available we display the organizational information. 

To be consistent, all the handler objects should have the common functionality to handle the request. To achieve this we use the following handler class which all the handlers should inherit. In this class we set the successor of the current object using the SetSuccessor() method. The Successor of an object should normally be more generic then the current object.

 

abstract class Handler

  {

    protected Handler successor;

    public void SetSuccessor(Handler successor)

    {

      this.successor = successor;

    }

    public abstract void HandleRequest(helpHandler handler);

  }

 

We define the following classes to implement the different handler objects.

 

DesignationHandler

SubDepartmentHandler

DepartmentHandler

OrganizationHandler

 

We use the following to set the successor of the current object and create the chain of objects.

 

designationHandler.SetSuccessor(subDepartmentHandler);

subDepartmentHandler.SetSuccessor(departmentHandler);

departmentHandler.SetSuccessor(organizationHandler);

 

If the current object can handle the request, it handles it otherwise it passes the request to the next object in the chain. The attached source code contains the complete implementation of this pattern which creates a chain of objects and passes the request along the chain.

 

COMMENT USING

Trending up