Click here to Skip to main content
Click here to Skip to main content

Design pattern FAQ part 4

By , 27 Mar 2011
 

Update done on explanation of Decorator Pattern, Composite Pattern and Template Pattern

Design Pattern FAQ Part 4

Introduction

This FAQ article is continuation to design pattern FAQ part 1 ,2 and 3 . In this article we will try to understand Bridge Pattern, Composite Pattern, Facade Pattern, Chain Of Responsibility, Proxy Pattern and Template pattern.

If you have not read my previous section you can always read from below

Part 1 Design pattern FAQ's -- factory pattern, abstract factory pattern, builder pattern, prototype pattern, singleton pattern and command pattern

Part 2 Design Pattern FAQ's -- Interpreter pattern, iterator pattern, mediator pattern, memento pattern and observer pattern

Part 3 Design Pattern FAQ's -- state pattern, strategy pattern, visitor pattern, adapter pattern and fly weight pattern


Can you explain bridge pattern?

Bridge pattern helps to decouple abstraction from implementation. With this if the implementation changes it does not affect abstraction and vice versa. Consider the figure ‘Abstraction and Implementation’. The switch is the abstraction and the electronic equipments are the implementations. The switch can be applied to any electronic equipment, so the switch is an abstract thinking while the equipments are implementations.

Figure: - Abstraction and Implementation

Let’s try to code the same switch and equipment example. First thing is we segregate the implementation and abstraction in to two different classes. Figure ‘Implementation’ shows how we have made an interface ‘IEquipment’ with ‘Start()’ and ‘Stop()’ methods. We have implemented two equipments one is the refrigerator and the other is the bulb.

Figure :- Implementation

The second part is the abstraction. Switch is the abstraction in our example. It has a ‘SetEquipment’ method which sets the object. The ‘On’ method calls the ‘Start’ method of the equipment and the ‘off’ calls the ‘stop’.

Figure: - Abstraction

Finally we see the client code. You can see we have created the implementation objects and the abstraction objects separately. We can use them in an isolated manner.

Figure :- Client code using bridge
 

Can you explain composite pattern?

GOF definition :- A tree structure of simple and composite objects

Many times objects are organized in tree structure and developers have to understand the difference between leaf and branch objects. This makes the code more complex and can lead to errors. 

For example below is a simple object tree structure where the customer is the main object which has many address objects and every address object references lot of phone objects.

Figure: - General Process

Now let’s say you want to insert the complete object tree. The sample code will be something as shown below. The code loops through all the customers, all addresses inside the customer object and all phones inside the address objects. While this loop happens the respective update methods are called as shown in the below code snippet.

foreach (Customer objCust in objCustomers)
{
objCust.UpDateCustomer();
 foreach (Address oAdd in objCust.Addresses)
 {
  oAdd.UpdateAddress();
 }
   foreach (Phone ophone in oAdd.Phones)
   {
     ophone.UpDatePhone();
   }
}

The problem with the above code is that the update vocabulary changes for each object. For customer its ‘UpdateCustomer’ , for address its ‘UpdateAddress’ and for phone it is ‘UpdatePhone’. In other words the main object and the contained leaf nodes are treated differently. This can lead to confusion and make your application error prone.

The code can be cleaner and neat if we are able to treat the main and leaf object uniformly. You can see in the below code we have created an interface (IBusinessObject) which forces all the classes i.e. customer, address and phone to use a common interface. Due to the common interface all the object now have the method name as “Update”.

foreach (IBusinessObject ICust in objCustomers)
{
ICust.Update();
  foreach (IBusinessObject Iaddress in ((Customer)(ICust)).ChildObjects)
   {
     Iaddress.Update();
foreach (IBusinessObject iphone in ((Address)(Iaddress)).ChildObjects)
      {
         iphone.Update();
}
   }
}

In order to implement composite pattern first create an interface as shown in the below code snippet.

public interface IBusinessObject
{
        void Update();
        bool isValid();
        void Add(object o);
       
}

Force this interface across all the root objects and leaf / node objects as shown below.

public class Customer : IBusinessObject
    {

        private List<Address> _Addresses;
        public IEnumerable<Address> ChildObjects
        {
            get
            {
                return (IEnumerable<Address>)_Addresses;
            }
        }
        public void Add(object objAdd)
        {
            _Addresses.Add((Address) objAdd);
        }
        public void Update()
        {
            
        }
        public bool isValid()
        {
            return true;
        }
}

Force the implementation on the address object also.

public class Address : IBusinessObject
    {
        private List<Phone> _Phones;

        public IEnumerable<Phone> ChildObjects
        {
            get
            {
                return (IEnumerable<Phone>)_Phones.ToList<object>();
            }
        }

        public void Add(object objPhone)
        {
            _Phones.Add((Phone)objPhone);
        }



        public void Update()
        {
           
        }

        public bool isValid()
        {
            return true;
        }

      
    }

Force the implementation on the last node object i.e. phone.

public class Phone : IBusinessObject
    {
        public void Update()
        {}
        public bool isValid()
        {return true;}
        public void Add(object o)
        {
            // no implementaton
         }
    }

Can you explain decorator pattern ?

Punch :- Decorator pattern adds dynamically stacked behavior thus helping us to change the behavior of the object on runtime.

There are situations where we would like to add dynamic stacked behavior to a class on runtime. The word stack is an important word to note. For instance consider the below situation where a hotel sells bread meals. They have four important products and the order can be placed using the below combination:-

  • Simple bread.
  • Bread with Chicken.
  • Bread with drinks
  • Bread with chicken and drinks.

In other words the order process behavior and the cost of the order changes on runtime depending on the type of the combination.

Figure: -

Below is a simple order with only bread which has two functions ‘prepare’ and ‘calculatecost’. We would like to add new products to this basic bread order dynamically on runtime depending on what the customer wants.

Below is a simple interface which every order will have i.e. Prepare and CalculateCost.

interface IOrder
{
string Prepare();
double CalculateCost();
}

The base product is the bread which implements the Iorder interface. We would like to add new products to the bread order and change the behavior of the complete order.

public class OrderBread : IOrder
    {
        public string Prepare()
        {
            string strPrepare="";
            strPrepare = "Bake the bread in oven\n";
            strPrepare = strPrepare + "Serve the bread";
            return strPrepare;
        }

        public double CalculateCost()
        {
            return 200.30;
        }
    }

We can alter the bread order dynamically using decorator pattern. To implement decorator pattern is a 5 steps process.

Step1:- Create a decorator class which aggregates the object / interface for which we need to add the behavior dynamically.

abstract class OrderDecorator : IOrder
    {
        protected IOrder Order;
	  . . . . .
	  . . . . .
	  . . . . .

    }

This decorator class will house the object and any method calls to the main object will first invoke all the housed objects and then the main object.

So for instance if you are calling the prepare method, this decorator class will invoke all the prepare methods of the housed object and then the final prepare method. You can see how the output changes when decorator comes in to picture.

Figure: -

Step 2: - The housed object/ interface pointer needs to be initialized. We can do the same by using various means for the sample below we will just expose a simple constructor and pass the object to the constructor to initialize the housed object.

abstract class OrderDecorator : IOrder
    {
        protected IOrder Order;
	  public OrderDecorator(IOrder oOrder)
        {
            Order = oOrder;
        }
	  . . . . .

    }

Step 3: - We will implement the Iorder interface and invoke the house object methods using the virtual methods. You can see we have created virtual methods which invoke the house object methods.

abstract class OrderDecorator : IOrder
    {
        protected IOrder Order;

        public OrderDecorator(IOrder oOrder)
        {
            Order = oOrder;
        }
        public virtual string Prepare()
        {
            return Order.Prepare();
        }

        public virtual double CalculateCost()
        {
            return Order.CalculateCost();
        }
    }

Step 4: - We are done with the important step i.e. creating the decorator. Now we need to create dynamic behavior object which can be added to the decorator to change object behavior on runtime.

Below is a simple chicken order which can be added to the bread order to create a different order all together called as chicken + bread order. The chicken order is created by inheriting from the order decorator class.

Any call to this object first invokes custom functionality of order chicken and then invokes the housed object functionality. For instance you can see When prepare function is called it first called prepare chicken functionality and then invokes the prepare functionality of the housed object.

The calculate cost also adds the chicken cost and the invokes the housed order cost to sum up the total.

class OrderChicken : OrderDecorator
    {
        public OrderChicken(IOrder oOrder) : base(oOrder)
        {
        }
        
         public override string Prepare()
        {
            return base.Prepare() +  PrepareChicken(); 
        }
        private string PrepareChicken()
        {
            string strPrepare = "";
            strPrepare = "\nGrill the chicken\n";
            strPrepare = strPrepare + "Stuff in the bread";
            return strPrepare;
        }
        public override double CalculateCost()
        {
            return base.CalculateCost() + 300.12;
        }
    }

Same way we can also prepare order drinks.

class OrderDrinks : OrderDecorator
    {
        public OrderDrinks(IOrder oOrder)
            : base(oOrder)
        {

        }
        public OrderDrinks()
        {
        }
public override string Prepare()
        {
            
            return base.Prepare() + PrepareDrinks();
        }
        private string PrepareDrinks()
        {
            string strPrepare = "";
            strPrepare = "\nTake the drink from freezer\n";
            strPrepare = strPrepare + "Serve in glass";
            return strPrepare;
        }

        public override double CalculateCost()
        {
            return base.CalculateCost() + 10.12;
        }
    }

Step 5:- The final step is see the decorator pattern in action. So from the client side you can write something like this to create a bread order.

IOrder Order =new OrderBread();
Console.WriteLine(Order.Prepare());
Order.CalculateCost().ToString();

Below is how the output will be displayed for the above client call.

Order 1 :- Simple Bread menu
Bake the bread in oven
Serve the bread
200.3

If you wish to create the order with chicken, drink and bread, the below client code will help you with the same.

Order = new OrderDrinks(new OrderChicken(new OrderBread()));
Order.Prepare();
Order.CalculateCost().ToString();

For the above code below is the output which combines drinks + chicken + bread.

Order 2 :- Drinks with chicken and bread
Bake the bread in oven
Serve the bread
Grill the chicken
Stuff in the bread
Take the drink from freezer
Serve in glass
510.54

In other words you can now attach these behaviors to the main object and change the behavior of the object on runtime.

Below are different order combination we can generate , thus altering the behavior of the order dynamically.

Order 1 :- Simple Bread menu
Bake the bread in oven
Serve the bread
200.3


Order 2 :- Drinks with chicken and bread
Bake the bread in oven
Serve the bread
Grill the chicken
Stuff in the bread
Take the drink from freezer
Serve in glass
510.54


Order 3 :- Chicken with bread
Bake the bread in oven
Serve the bread
Grill the chicken
Stuff in the bread
500.42


Order 4 :- drink with simple bread
Bake the bread in oven
Serve the bread
Take the drink from freezer
Serve in glass
210.42

(A) Can you explain Façade pattern?

Façade pattern sits on the top of group of subsystems and allows them to communicate in a unified manner.

Figure: - Façade and Subsystem

Figure ‘Order Façade’ shows a practical implementation of the same. In order to place an order we need to interact with product, payment and invoice classes. So order becomes a façade which unites product, payment and invoice classes.

Figure: - Order Facade

Figure ‘façade in action’ shows how class ‘clsorder’ unifies / uses ‘clsproduct’,’clsproduct’ and ‘clsInvoice’ to implement ‘PlaceOrder’ functionality.

Figure :- Façade in action

 

Can you explain chain of responsibility ( COR)?

Chain of responsibility is used when we have series of processing which will be handled by a series of handler logic. Let’s understand what that means. There are situations when a request is handled by series of handlers. So the request is taken up by the first handler, he either can handle part of it or can not, once done he passes to the next handler down the chain. This goes on until the proper handler takes it up and completes the processing.

Figure: - Concept of Chain of Responsibility

Let’s try to understand this concept by a small sample example. Consider figure ‘Sample example’ where we have some logic to be processed. So there are three series of processes which it will go through. So process 1 does some processing and passes the same to process 2. Process 2 does some kind of processing and passed the same to process 3 to complete the processing activity.

Figure: - Sample example

Figure ‘class diagram for COR’ the three process classes which inherit from the same abstract class. One of the important points to be noted is that every process points to the next process which will be called. So in the process class we have aggregated one more process object called as ‘objProcess’. Object ‘ObjProcess’ points to next process which should be called after this process is complete.

Figure: - Class diagram for COR

Now that we have defined our classes its time to call the classes in the client. So we create all the process objects for process1 , process2 and process3. Using the ‘setProcess’ method we define the link list of process objects. You can see we have set process2 as a link list to process1 and process2 to process3. Once this link list is established we run the process which in turn runs the process according to the defined link list.

Figure: - COR client code

Can you explain proxy pattern?

Proxy fundamentally is a class functioning as in interface which points towards the actual class which has data. This actual data can be a huge image or an object data which very large and can not be duplicated. So you can create multiple proxies and point towards the huge memory consuming object and perform operations. This avoids duplication of the object and thus saving memory. Proxies are references which points towards the actual object.

Figure ‘Proxy and actual object’ shows how we have created an interface which is implemented by the actual class. So the interface ‘IImageProxy’ forms the proxy and the class with implementation i.e. ‘clsActualImage’ class forms the actual object. You can see in the client code how the interface points towards the actual object.

Figure: - Proxy and actual object

The advantages of using proxy are security and avoiding duplicating objects which are of huge sizes. Rather than shipping the code we can ship the proxy, thus avoiding the need of installing the actual code at the client side. With only the proxy at the client end we ensure more security. Second point is when we have huge objects it can be very memory consuming to move to those large objects in a network or some other domain. So rather than moving those large objects we just move the proxy which leads to better performance.

Can you explain template pattern?

Template pattern is a behavioral pattern. Template pattern defines a main process template and this main process template has sub processes and the sequence in which the sub processes can be called. Later the sub processes of the main process can be altered to generate a different behavior.

Punch :- Template pattern is  used in scenarios where we want to create  extendable behaviors in generalization and specialization relationship.

For example below is a simple process to format data and load the same in to oracle. The data can come from various sources like files, SQL server etc. Irrespective from where the data comes, the overall general process is to load the data from the source, parse the data and then dump the same in to oracle.

Figure: - General Process

Now we can alter the general process to create a CSV file load process or SQL server load process by overriding ‘Load’ and ‘Parse’ sub process implementation.

Figure: - Template thought Process

You can see from the above figure how we have altered ‘Load’ and ‘Parse’ sub process to generate CSV file and SQL Server load process. The ‘Dump’ function and the sequence of how the sub processes are called are not altered in the child processes.

In order to implement template pattern we need to follow 4 important steps:-

  1. Create the template or the main process by creating a parent abstract class.
  2. Create the sub processes by defining abstract methods and functions.
  3. Create one method which defines the sequence of how the sub process methods will be called. This method should be defined as a normal method so that we child methods cannot override the same.
  4. Finally create the child classes who can go and alter the abstract methods or sub process to define new implementation.
public abstract class GeneralParser
    {
        protected abstract void Load();

        protected abstract void Parse();
        protected virtual void Dump()
        {
            Console.WriteLine("Dump data in to oracle");
        }
        public void Process()
        {
            Load();
            Parse();
            Dump();
        }
    }

The ‘SqlServerParser’ inherits from ‘GeneralParser’ and overrides the ‘Load’ and ‘Parse’ with SQL server implementation.

public class SqlServerParser : GeneralParser
    {
        protected override void Load()
        {
            Console.WriteLine("Connect to SQL Server");
        }
        protected override void Parse()
        {
            Console.WriteLine("Loop through the dataset");
        }     
       
    }

The ‘FileParser’ inherits from General parser and overrides the ‘Load’ and ‘Parse’ methods with file specific implementation.

public class FileParser : GeneralParser
    {
        protected override void Load()
        {
            Console.WriteLine("Load the data from the file");
        }
        protected override void Parse()
        {
            Console.WriteLine("Parse the file data");
        }
     
    }

From the client you can now call both the parsers.

FileParser ObjFileParser = new FileParser();
ObjFileParser.Process();
Console.WriteLine("-----------------------");
SqlServerParser ObjSqlParser = new SqlServerParser();
ObjSqlParser.Process();
Console.Read();

The outputs of both the parsers are shown below.

Load the data from the file
Parse the file data
Dump data in to oracle
-----------------------
Connect to SQL Server
Loop through the dataset
Dump data in to oracle

In case your are completely new to design patterns or you really do not want to read this complete  article do see our free design pattern Training and interview questions / answers videos.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Shivprasad koirala
Architect http://www.questpond.com
India India
Member

I am a Microsoft MVP for ASP/ASP.NET and currently a CEO of a small
E-learning company in India. We are very much active in making training videos ,
writing books and corporate trainings. Do visit my site for 
.NET, C# , design pattern , WCF , Silverlight
, LINQ , ASP.NET , ADO.NET , Sharepoint , UML , SQL Server  training 
and Interview questions and answers


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhat/where is the difference between a bridge Pattern and dependency injection?memberCyron436 Jan '13 - 2:46 
I have already asked this question in two different forums but I never got an answer.
So I try again here.
When I look at bridge pattern samples (yours and that over at DoFactory), all I can see is the usual dependency injection (interface injection to be more precise).
Am I missing something or is the bridge pattern really just another name for dependency injection?
Greetings,
Cyron

AnswerRe: What/where is the difference between a bridge Pattern and dependency injection?memberLeandro Taset2 May '13 - 6:28 
Hello there. Have you figured this out yet...? It seems like you're trying to find out the difference between a sheep and a necktie. Sure, they might both have some wool in them, but their respective usages are largely unrelated, yet peculiarly compossible if you want to make a well respected geek-looking sheep by combining both, plus adding some glasses. Poke tongue | ;-P
 
Now seriously: you could say that the bridge pattern inherently implies the use of some kind of dependency injection mechanism in order for it to work, sort of speak. Separation of concerns, decoupling, cohesion. You hear all that here and there when discussing software design with anyone, but just some few ever mention that, in real life, you have to somehow integrate the parts you're "decoupling" in the first place. Sometimes this fact is overlooked, and fellow programmers find themselves in situations where they don't know how to move out of the over-design "phase" (myself, sometime). Dependency injection is the "somehow" in this case for the bridge pattern.
 
Please note that I've used the term "dependency injection" as general theoretical concept here, not related to any solution around that magically "does the trick" for us in practice. You don't need Ninject, nor LinFu, nor anything else alike to implement the bridge pattern (just to be clear).
 
This GoF pattern strives for decoupling an abstraction from its own myriad of possible specializations and their respective implementations, so that both "hierarchies" can vary independently (and I'm almost textually quoting the seminal book of "Gamma et al"). In that respect, perhaps the example included in this article is not the most illustrative one.
 
Hope this helps or, on the other hand, at least piles up on your confusion, so you keep asking questions (to someone else). Laugh | :laugh:
 
Cheers:
Taset.
Anything that could possibly go wrong in some moment, will definitely go wrong in the worst possible moment...
In the worst way that could be possible!

–Finagle's corollary to Murphy's Law (paraphrased).


QuestionRealtime use of CoR patternmemberAchintya Jha1 Oct '12 - 5:39 
Shiv,
This is the simplest explanation of Chain of Responsibility which has I think very limited use in realtime.
How can I pass and return parameters from the different execute methods.
Suppose ClassA.RunProcess returns a Datatable which is to be used by ClassB or ClassC's RunProcess ?
Any pointers ?
Thanks
GeneralUpdated the article with some design pattern which had errorsmvpShivprasad koirala21 Mar '11 - 1:29 
Updated the article with some design pattern which had errors , let me know if there are still concerns. thanks
My book .NET interview questions with 500 mostly asked questions in .NET world .NET Interview questions and answers

GeneralMy vote of 1memberhandled116 Mar '11 - 7:56 
Of the examples I have read, they are plain wrong. No idea how the author can be a CEO of an e-learning company!
GeneralRe: My vote of 1mvpShivprasad koirala16 Mar '11 - 8:56 
I agree to your below comments. For long time i want to update these two patterns which i explained wrongly. Thanks for your effort. Its not you i get regular comments for these two.
 
I will update the above patterns in this week. Thanks and sorry for all trouble.
My book .NET interview questions with 500 mostly asked questions in .NET world .NET Interview questions and answers

GeneralRe: My vote of 1mvpShivprasad koirala21 Mar '11 - 1:29 

Shivprasad koirala wrote:
I will update the above patterns in this week. Thanks and sorry for all
trouble.


 
I have updated the article let me know if there still concerns...
My book .NET interview questions with 500 mostly asked questions in .NET world .NET Interview questions and answers

GeneralRe: My vote of 1mvpShivprasad koirala16 Mar '11 - 8:57 
handled1 wrote:
No idea how the author can be a CEO of an e-learning company

ahhh its my own firm so....I understand your frustration.
My book .NET interview questions with 500 mostly asked questions in .NET world .NET Interview questions and answers

Rant[My vote of 1] Again, your explanation of the template pattern is totally wrong!!memberhandled116 Mar '11 - 7:54 
Im not going to read any more of your patterns because the only 2 I have read are wrong! Anyone reading this page - please, please be wary that the only ones I've read are wrong - go here for a proper explanation: http://en.wikipedia.org/wiki/Template_method_pattern[^]. Your explanation of the template pattern simply describes normal inheritance using an abstract base class (much like your composite explanation w.r.t. interfaces)! Inheritance is not a design pattern, it comes for free with OOP. The template pattern is supposed to be there to describe the general workflow structure in a class, and letting subclasses implement the behaviour.
GeneralComposite Pattern Explanation is wrongmemberhandled116 Mar '11 - 7:38 
Hi - your composite explanation is incorrect. You simply specify an interface then get a load of objects to implement it. This is just using an interface, not the composite pattern! None of your objects are composed of any other objects. I'm a bit suprised as I see your exact explanation posted in quite a few places on the web. If you want a proper explanationthen please look here: http://en.wikipedia.org/wiki/Composite_pattern
GeneralMy vote of 5memberShahriar Iqbal Chowdhury24 Nov '10 - 9:23 
Good one, nice, detailed and simple. Thanks for sharing
Generalgreat againmemberDonsw4 Feb '09 - 14:57 
As usual the article is excellent. I have gone through some of my pattern books and not seen all of the ones you have talked about. Is there a book that contains all of these?
GeneralAgain Thanks SirmemberAbhijit Jana6 Sep '08 - 4:12 
This is Third article i am reading today itself . Great Representation !!!
 
all though i need to learn in details so i am also studing for GoF Book . But this is very very good Startup !!!!
 
Thanks Again !!!!!!
 

GeneralThanks...memberAaron Jackson2 Sep '08 - 17:31 
I'm certain that many of us know these questions, but one of the biggest problems I face when asking questions is organizing which questions I want to ask. I have a set of documents that I keep handy that include a set of questions that I like to start with ... why? Consistency between candidates, less chaos in my already chaotic life and an overall cohesive theme to my opening questioning (yes, I vary it afterwards). These questions are a tool that make it a little easier for me to start an interview with.
 
So, thanks.

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 28 Mar 2011
Article Copyright 2008 by Shivprasad koirala
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid