Click here to Skip to main content
15,886,110 members
Articles / Programming Languages / C#
Article

Chain of Responsibility Pattern

Rate me:
Please Sign up or sign in to vote.
2.33/5 (6 votes)
29 Jun 20073 min read 25.8K   249   20   1
This article discusses a how to make a custom wizard control using the Chain of Responsibility pattern

Introduction

This article shows a how to make a custom Wizard control using the Chain of Responsibility pattern, which passes and returns data between each step. This sample creates a wizard control through Windows Forms. Every step is responsible for its own validation and responsibility is broken on each step rather then a single form. Previously we implemented this through panels or counter values, but using these techniques we will face some difficulty passing the data from one screen to another. I have tried a lot because I was building an interactive wizard control where each slide is responsible for each. I had searched for solutions, but I have found no other fruitful result.

Scope

Windows Forms, C#, VB.NET, Visual Basic, Java

Implications of using the Chain of Responsibility pattern

Our intent is to delegate the responsibility of each screen (Form) so that each one is responsible for its own request and validation. Chain of Responsibility is the pattern that addresses this problem by decoupling the sender and request handler.

Class code

In this approach, I have a responsibility class that contains the IHandler in the Linked List fashion, as described by the image below:

Screenshot - image1.jpg

We have a Master Form that has a panel containing a control, which is used on runtime as the defined condition satisfied. Every control is added into the master panel on runtime. We therefore have IHandler and three methods: GetRequest(), ProcessRequest() and Validate(). As you will see, these method implementations depend on the user. I just describe the Chain of Responsibility Pattern in Wizard Control. This is a common problem for all WinForm developers, especially those working in products. ChainHandler holds the reference of IHandler because in this example, chain handler is like a linked list. So, every chainhandler has a reference of IHandler.

C#
public ChainHandler(IHandler currentHandler)
{
    this.handler = currentHandler;
}

The AddNext() method actually holds the next reference of the chain. Because the current reference should be the previous of next, nexthandler holds the reference of current as a pervious.

C#
public void AddNext(ChainHandler  nextHandler)
{
    this.nextHandle = nextHandler;
    nextHandle.AddPrevious(this);
}

Add previous holds the previous reference of the current object.

C#
public void AddPrevious(ChainHandler previousHandler)
{
    this.previousHandle = previousHandler;
}

It will return the handler reference that ChainHanlder currently contains.

C#
public IHandler GetCurrentHandle()
{
    return this.handler;
}

This function's responsibility is to return the next reference of the chain.

C#
public ChainHandler GetNext()
{
    return this.nextHandle;
}

This function's responsibility is to return the previous reference of the chain.

C#
public ChainHandler GetPrevious()
{
    return this.previousHandle;
}

The interesting thing in this example is that the chain and IHandler both have responsibilities. In my case, I have to use controls in my different screen. That's why chain contains the references of IHandler.

Build chain

On Main or start-up of the application, we have to build the chain in this way.

C#
private static void Start()
{
    Code.ChainHandler objchain1 = 
        new ChainOfResponsibility.Code.ChainHandler(new Controls.First());
    Code.ChainHandler objchain2 = 
        new ChainOfResponsibility.Code.ChainHandler(new Controls.Second());
    Code.ChainHandler objchain3 = 
        new ChainOfResponsibility.Code.ChainHandler(new Controls.Third());
    Code.ChainHandler objchain4 = 
        new ChainOfResponsibility.Code.ChainHandler(new Controls.Fourth());

    objchain1.AddNext(objchain2);
    objchain2.AddNext(objchain3);
    objchain3.AddNext(objchain4);

    Application.EnableVisualStyles();
    Application.Run(new Form1(objchain1));
}

Transfer data between chains

We have requested an object that contains the data of each object to another object. Every request can save its data in request using the AddRequst() method.

C#
public void AddRequest(object key ,object value)
{
    if (objrequestCollection == null)
    {
        objrequestCollection = new Hashtable();
    }
    objrequestCollection.Add(key, value); 
}

Similarly, the delegated responsible request handler will get the data via GetReqeuest.

C#
public object GetRequest(object key)
{
    return objrequestCollection[key];
}

Check before ReqeustProcessing

C#
public bool IsRequestProcess
{
    get { return isRequestProcess; }
    set { isRequestProcess = value; }
}

Every request is responsible for setting the isRequestProceess attribute to true/false. Then the next responsible object will decide either to process the request or not. So, every time the request will not process until the attribute value is set to true.

Another implementation

Screenshot - image2.jpg

The interesting thing in this implementation is that ChainHandler is acting like a linked list handler because it knows its next and previous ChainHandler. So, every chain handler contains the IHandler.

IHandler code

C#
public interface IHandler
{
    void ProcessRequest(Request req);
    Request GetRequest();
    bool Validate();
    Panel GetPanel();
}

Another implementation

We can also implement this through some collection objects like arraylist, hashtable, hashmap, etc. However, in this we have to pay special attention to the limits.

Future development

This bit is pretty much up to you guys. If anyone makes any valid suggestions, I'd be more than happy to implement them.

History

Version 1.0 (25 June 2007) - Initial release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Pakistan Pakistan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhat about events and delegates? Pin
Philip Laureano29-Jun-07 13:42
Philip Laureano29-Jun-07 13:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.