Click here to Skip to main content
15,881,678 members
Articles / Programming Languages / C#

Facade Design Pattern (C#)

Rate me:
Please Sign up or sign in to vote.
4.84/5 (53 votes)
6 May 2014CPOL5 min read 101.1K   51   26
Implementing Facade design pattern in C#

Introduction

This article presents the strength of the facade desing pattern and provides us an overview as to when this pattern should be used. The source code is implemented in C#.

Background

FACADE is yet another a very important structural design pattern. Literally speaking the term facade means “outward appearance”. As we have noted that many of the design patterns in software development were inspired/ inherited from construction industry. So I can look upon the facade pattern as one which was directly imbibed from construction industry. So facade (be it in software or civil engineering) shows us a simple outward projection/view of a large system, be it a house or be it a large software system. So you can look out in the figure below of the house, what we see here is a facade of the house.

Image 1

Just looking at the facade of the house the viewer would not know how the internal building blocks of the house have come up together which resulted in this big house.
Similiarly in software design we may often have to incorporate “facade” design pattern when we are dealing with a large system. The need for facade design pattern (only in terms of software from hereon) would arise when you want to invoke a lot of subsystems of a bigger system from one point(client). According to the Gof book facade design pattern can be defined as:

Definition(from Gof book):- “Facade provides a unified interface to a set of interfaces in a subsystem”.

So it is clear if the software system is composed of number of subsystems (which generally is the case) we may want to create a “facade” object which would call all these subsystems from one place. The main adavantages of incorporating a facade pattern are:
1) It provides a single simplified interface and hence makes the subsystems easier to use.
2) The client code is shielded from creating various objects of subsystem. This would be taken care of facade object.
3) Facade object decouples the subsystem from the client and other subsystems.
Image 2

Using the code

Let us look at a code example where we can apply facade.

The online shopping store has to process a series of complicated steps before it ships your favorite product at your address. These steps can be updating their inventory, verifying your shipping address for delivery, verifying your credit card details, applying various discounts and what not. Since all these steps are complicated so suppose each step forms a subsystem of the larger system (online ordering). When the online store performs these operations it may want to call a single operation say “FinalizeOrder” which would in turn call all these subsytems. We can sense this may be the perfect place where we can apply facade pattern. So we will create a facade object which would call the sybsystems which are: InventoryUpdate, AddressVerification, Discounting, PayCardVerification, Shipping.Imagine we don’t create a facade object then from the client code we would create 5 different objects which in turn would perform these operations. Although this is not wrong but it looks messy. Now imagine the same steps have to be performed from some other place in their site or may be from their mobile application. Do we really want to write that messy code of creating objects of subsystems and call their respective operations? This would definitely pollute the client code. Facade object instead would come for our rescue and would make the subsystems easier to use.
Let’s look at the code for online shopping which would make things clear. We would first see the code without facade and then with facade object. Below are the various subsystems of the online shopping system which are self explanatory. Please note that I have made every class and its method very abstract, they do not have any business implementations here and are totally dummy.

Sub-system for inventory management.

interface IInventory
{
   void Update(int productId);
}


class InventoryManager:IInventory
   {
       public void Update(int productId)
       {
           Console.WriteLine(string.Format("Product# {0} is subtracted from the store's
                                            inventory." , productId));
       }
   }

Sub-system for order verification

interface IOrderVerify
{
  bool VerifyShippingAddress(int pincode);
}



class OrderVerificationManager:IOrderVerify
{

   public bool VerifyShippingAddress(int pincode)
   {
     Console.WriteLine(string.Format("The product can be shipped to the pincode {0}.",
                                      pincode));
    return true;
   }
}

Sub-system for discounts and costing.

interface ICosting
{
   float ApplyDiscounts(float price,float discountPercent);
}


class CostManager:ICosting
{

   public float ApplyDiscounts(float price,float discountPercent)
   {
      Console.WriteLine(string.Format("A discount of {0}% has been applied on the product's 
                                       price of {1}", discountPercent,price));            
      return price - ((discountPercent / 100) * price);
   }
}

Sub-system for payment gateway.

interface IPaymentGateway
{
  bool VerifyCardDetails(string cardNo);
  bool ProcessPayment(string cardNo, float cost);
}


class PaymentGatewayManager:IPaymentGateway
{
   public bool VerifyCardDetails(string cardNo)
   {
      Console.WriteLine(string.Format("Card# {0} has been verified and is accepted.", 
                                       cardNo));
      return true;
   }

   public bool ProcessPayment(string cardNo, float cost)
   {
      Console.WriteLine(string.Format("Card# {0} is used to make a payment of 
                                       {1}.",cardNo,cost));
      return true;
   }
}

Sub-system for Logistics.

interface ILogistics
{
  void ShipProduct(string productName, string shippingAddress);
}



class LogisticsManager:ILogistics
{
   public void ShipProduct(string productName, string shippingAddress)
   {
      Console.WriteLine(string.Format("Congratulations your product {0} has been shipped 
                                       at the following address: {1}", productName, 
                                       shippingAddress));
   }
}

Below is another class (kind of badly written data model) which would complete our system.

class OrderDetails
{
   public int ProductNo { get; private set; }
  
   public string ProductName { get; private set; }
   public string ProductDescription { get; private set; }
   public float Price { get; set; }
   public float DiscountPercent { get; private set; }
   public string AddressLine1 { get; private set; }
   public string AddressLine2 { get; private set; }
   public int PinCode { get; private set; }
   public string CardNo { get; private set; }

   public OrderDetails(string productName, string prodDescription, float price, 
                       float discount, string addressLine1,string addressLine2,
                       int pinCode,string cardNo)
   {
     this.ProductNo = new Random(1).Next(1,100);
     this.ProductName = productName;
     this.ProductDescription = prodDescription;
     this.Price = price;
     this.DiscountPercent = discount;
     this.AddressLine1 = addressLine1;
     this.AddressLine2 = addressLine2;
     this.PinCode = pinCode;
     this.CardNo = cardNo;
   }
}

These are the sub-systems which pretty much forms the bigger system “The online shoppping system”. Now the online shopping system needs to call these sub-systems, let’s see how our code would be when we give a call to them from the client.

class Program
{
  static void Main(string[] args)
  {
    // Creating the Order/Product details
    OrderDetails orderDetails = new OrderDetails("C# Design Pattern Book",
                                                 "Simplified book on design patterns in 
                                                  C#",
                                                  500,
                                                  10,
                                                  "Street No 1",
                                                  "Educational Area",
                                                  1212,
                                                  "4156213754"
                                                 );
            
   // Client Code without Facade.

  // Updating the inventory.
     IInventory inventory = new InventoryManager();
     inventory.Update(orderDetails.ProductNo);

  // Verfying various details for the order such as the shipping address.
     IOrderVerify orderVerify = new OrderVerificationManager();
     orderVerify.VerifyShippingAddress(orderDetails.PinCode);

    

  // Calculating the final cost after applying various discounts.
     ICosting costManger = new CostManager();
     orderDetails.Price=costManger.ApplyDiscounts(orderDetails.Price, 
                                                  orderDetails.DiscountPercent
                                                 );

  // Going through various steps if payment gateway like card verification, charging from 
    the card.
    IPaymentGateway paymentGateWay = new PaymentGatewayManager();
    paymentGateWay.VerifyCardDetails(orderDetails.CardNo);
    paymentGateWay.ProcessPayment(orderDetails.CardNo, orderDetails.Price);

 // Completing the order by providing Logistics.
    ILogistics logistics = new LogisticsManager();
    logistics.ShipProduct(orderDetails.ProductName, string.Format("{0}, {1} - {2}.", 
                          orderDetails.AddressLine1, orderDetails.AddressLine2, 
                          orderDetails.PinCode));
        }
    }

Below is the output of the program.

Image 3

The code above has lot of issues as far as code cleanliness is concerned. The client code is very messy. The client (main program) has to create objects of all the sub-systems in order to
call them furthermore it makes the client code tightly coupled with various objects in the system.

In order to clean the client code so that it does not have to worry about various objects in the system we would create a “facade” object. The facade object would provide us a simplified
interface by which other interfaces can be called.

Let's look at the facade object.

class OnlineShoppingFacade
{
   IInventory inventory = new InventoryManager();
   IOrderVerify orderVerify = new OrderVerificationManager();
   ICosting costManger = new CostManager();
   IPaymentGateway paymentGateWay = new PaymentGatewayManager();
   ILogistics logistics = new LogisticsManager();

   public void FinalizeOrder(OrderDetails orderDetails)
   {
      inventory.Update(orderDetails.ProductNo);
      orderVerify.VerifyShippingAddress(orderDetails.PinCode);
      orderDetails.Price = costManger.ApplyDiscounts(orderDetails.Price, 
                                                     orderDetails.DiscountPercent);           
      paymentGateWay.VerifyCardDetails(orderDetails.CardNo);
      paymentGateWay.ProcessPayment(orderDetails.CardNo, orderDetails.Price);
      logistics.ShipProduct(orderDetails.ProductName, string.Format("{0}, {1} - {2}.", 
                            orderDetails.AddressLine1, orderDetails.AddressLine2, 
                            orderDetails.PinCode));
   }
}

So the façade object has exposed us a method “FinalizeOrder” through which all the methods of the various sub-systems are called.

Let’s look at the client code which would be using this façade object to call the sub-system’s.

static void Main(string[] args)
        {
            // Creating the Order/Product details
            OrderDetails orderDetails = new OrderDetails("C# Design Pattern Book",
                                                         "Simplified book on design patterns in C#",
                                                         500,
                                                         10,
                                                         "Street No 1",
                                                         "Educational Area",
                                                         1212,
                                                         "4156213754"
                                                         );

            // Using Facade
            OnlineShoppingFacade facade = new OnlineShoppingFacade();
            facade.FinalizeOrder(orderDetails);

            Console.ReadLine();
            
        }

Below is the output which we get.

Image 4

The output confirms that the “facade” object works in exactly the same manner but it makes the client code clutter free and relieves client code of handling various objects and calling methods associated with these objects.

Points of Interest

That ends our article with “Facade” pattern we would have realized by now that we should have used facade at so many places and that would have given our code a better shape. You can figure out the advantages of this pattern by realizing that it would provide us a unified interface which can be used to call other interfaces. Also imagine if we need to call the above sub-systems from say the mobile app of the online shopping site, we would simply use and call the exposed facade object rather than creating individual objects of the sub system and calling them from the mobile app code.

History

Version 1.0- (30/04/2014)

License

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


Written By
Team Leader
United States United States
I am a software developer by profession presently working as an Lead Software Engineer in New York City. My passion is technology. I like to learn new things every day and improve my skills in terms of technology. I feel software development can be made very interesting if we inculcate the habit of "beautiful thinking".

Comments and Discussions

 
GeneralHI Pin
ishantissera27-Mar-16 19:16
ishantissera27-Mar-16 19:16 
GeneralRe: HI Pin
Rahul Dhammy28-Mar-16 8:12
professionalRahul Dhammy28-Mar-16 8:12 
GeneralMy Vote Of 4 Pin
Alireza_136229-Jul-15 21:12
Alireza_136229-Jul-15 21:12 
GeneralRe: My Vote Of 4 Pin
Rahul Dhammy30-Jul-15 6:37
professionalRahul Dhammy30-Jul-15 6:37 
GeneralMy vote of 4 Pin
Suvendu Shekhar Giri5-Apr-15 19:29
professionalSuvendu Shekhar Giri5-Apr-15 19:29 
GeneralRe: My vote of 4 Pin
Rahul Dhammy6-Apr-15 4:42
professionalRahul Dhammy6-Apr-15 4:42 
GeneralNice article. Pin
anilh.chavan29-Mar-15 19:52
anilh.chavan29-Mar-15 19:52 
GeneralRe: Nice article. Pin
Rahul Dhammy30-Mar-15 7:12
professionalRahul Dhammy30-Mar-15 7:12 
GeneralGood article. Pin
anilh.chavan29-Mar-15 19:52
anilh.chavan29-Mar-15 19:52 
GeneralMy vote of 5 Pin
Justin Shepertycki7-Jun-14 8:34
Justin Shepertycki7-Jun-14 8:34 
GeneralRe: My vote of 5 Pin
Rahul Dhammy7-Jun-14 9:38
professionalRahul Dhammy7-Jun-14 9:38 
QuestionMy 5 Pin
Govindaraj Rangaraj13-May-14 23:34
Govindaraj Rangaraj13-May-14 23:34 
AnswerRe: My 5 Pin
Rahul Dhammy14-May-14 2:45
professionalRahul Dhammy14-May-14 2:45 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun11-May-14 21:28
Humayun Kabir Mamun11-May-14 21:28 
GeneralRe: My vote of 5 Pin
Rahul Dhammy11-May-14 22:02
professionalRahul Dhammy11-May-14 22:02 
GeneralMy vote of 3 Pin
CodeChecker 56897-May-14 3:41
CodeChecker 56897-May-14 3:41 
GeneralMy vote of 5 Pin
Malli_S5-May-14 20:03
Malli_S5-May-14 20:03 
GeneralRe: My vote of 5 Pin
Rahul Dhammy30-Mar-15 7:14
professionalRahul Dhammy30-Mar-15 7:14 
Questionthank you. Pin
wangfnso5-May-14 17:05
wangfnso5-May-14 17:05 
AnswerRe: thank you. Pin
Rahul Dhammy30-Mar-15 7:14
professionalRahul Dhammy30-Mar-15 7:14 
GeneralMy vote of 4 Pin
M Rayhan4-May-14 21:58
M Rayhan4-May-14 21:58 
QuestionWouldn't the Builder pattern be better here? Pin
George Swan4-May-14 21:02
mveGeorge Swan4-May-14 21:02 
AnswerRe: Wouldn't the Builder pattern be better here? Pin
Rahul Dhammy5-May-14 2:28
professionalRahul Dhammy5-May-14 2:28 
GeneralRe: Wouldn't the Builder pattern be better here? Pin
George Swan5-May-14 3:45
mveGeorge Swan5-May-14 3:45 
GeneralMy vote of 4 Pin
darshan joshi4-May-14 20:56
darshan joshi4-May-14 20:56 

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.