An introduction to Design Pattern – Part 3

Posted: May 22, 2011 in CodeProject, Design Pattern, OOP
Prerequisite

Before reading this article, you should read the first and second part of this series.

Delegation

When a client object X requests some service from an object Y, then Y may decide to pass this request to another object Z instead of handling the request by itself. When this happens, we say that receiver object Y has delegated its operation to its delegate Z. This process is known as delegation and it’s a way of making object composition as powerful for reuse as inheritance.

Let us now consider an example from this famous book on design patterns. Suppose that we want to create a class which will generate a window.  The code for this class may look something like below –

/* We are using an interface so that all window drawing classes have a
 * common Object Interface (Remember the OOP principle 1 from first part? ) 
 */
public class Window
{
    // Various member variables
    public void drawWindow()
    {
        // Code to draw the window
    }

    // various other methods
}

This approach is a naive one. A better approach would be to create a Rectangle class which will contain the logic to generate a simple rectangle and then inherit this Window class from this rectangle and thereby including its functionality.

However, there is another approach. Instead of inheriting this Window class from Rectangle, we may delegate the responsibility from this class to another class called DrawRectangleShape like this –

public interface DrawWindow 
{
    public void draw(Window X);
}

public class DrawRectangleShape implements DrawWindow
{
    // various data and methods

    public void draw(Window X)
    {
        // logic to generate a rectangular-shaped window X
    }
}

public class Window
{
    DrawWindow windowDrawer;
    // Various member variables

    public Window()
    {
        /* It is OK to initialize this windowDrawer reference to a particular
         * object instance, but you should also provide setter method so that
         * this reference can be changed dynamically.
         */
        this.windowDrawer = new DrawRectangleShape();
    }

    public void setWindowDrawer(IDrawWindow windowDrawer)
    {
        this.windowDrawer = windowDrawer;
    }

    public void draw()
    {
        this.windowDrawer.draw(this)        // Pass self-reference to the delegate
    }

    public void redraw()
    {
        // destroys the current window, then regenerates it
    }

    // various other methods
}

Now if you look at the code you’ll see that the Window object is passing itself to the delegate so that the delegate can properly generate a rectangular window. This is always the case when the delegate requires a reference to the receiver.

Now why should we use delegation?

The main advantage of delegation is that it makes it easy to compose behaviors at run-time. Consider another implementation of the IDrawWindow interface –

public class DrawCircularShape implements DrawWindow
{
    // various data and methods

    public void draw(Window X)
    {
        // logic to generate a circular-shaped window X
    }
}

Now consider the following piece of code –

Window newWindow = new Window();
newWindow.draw();

DrawWindow newWindowDrawer = new DrawCircularShape();
newWindow.setWindowDrawer(newWindowDrawer);
newWindow.redraw();

The above piece of code first generates a rectangular-shaped window. After that, it replaces its default rectangular shape drawer with a circular shape drawer and then redraws itself. As a result, the window will become circular from rectangular at run-time!!!

So, using delegation you can change the behaviors of objects at run-time in this way. A lots of design patterns make use of this technique.

Unfortunately, delegation has some disadvantages too. Dynamic, highly parameterized software is typically harder to understand than more static software. If you delegation then you will have codes that changes behaviors at run-time. Understanding these varying behaviors may prove to be difficult. There are also some run-time inefficiency since you have to create new objects and transfer responsibilities to them, but this is negligible because most of the modern processors are pretty fast and because of the flexibility it brings to a software design.

So when using delegation, always make sure that it simplifies the design more than it complicates. Only then you will be able to leverage the true power of delegation.

Conclusion

At this point you should have a pretty good understanding of what design patterns are and what do they accomplish. You will find various other definitions on various books and on the web. I think you will now understand all of them 🙂 . Read them on your own. For the time being, I am going to include the definition of design patterns given by Christopher Alexander who first introduced the idea –

The elements of this language are entities called patterns. Each pattern describes a problem that occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.

I hope someone finds this series useful 🙂 .

Advertisements
Comments
  1. Rezaul Karim says:

    Great Stuff Sayem. Keep it up 🙂

  2. James says:

    Written considerably well done.
    I want to see more!

    • sayem.bd says:

      Thank you James. On every weekend I will try to write about at least one pattern if I can manage some free time. Each of these will focus on various OOP principles and how the pattern applies it to solve a problem.

      Next week I will write about Strategy pattern – my favorite 🙂 .

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