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.
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.
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)
{
OrderDetails orderDetails = new OrderDetails("C# Design Pattern Book",
"Simplified book on design patterns in
C#",
500,
10,
"Street No 1",
"Educational Area",
1212,
"4156213754"
);
IInventory inventory = new InventoryManager();
inventory.Update(orderDetails.ProductNo);
IOrderVerify orderVerify = new OrderVerificationManager();
orderVerify.VerifyShippingAddress(orderDetails.PinCode);
ICosting costManger = new CostManager();
orderDetails.Price=costManger.ApplyDiscounts(orderDetails.Price,
orderDetails.DiscountPercent
);
the card.
IPaymentGateway paymentGateWay = new PaymentGatewayManager();
paymentGateWay.VerifyCardDetails(orderDetails.CardNo);
paymentGateWay.ProcessPayment(orderDetails.CardNo, orderDetails.Price);
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.
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)
{
OrderDetails orderDetails = new OrderDetails("C# Design Pattern Book",
"Simplified book on design patterns in C#",
500,
10,
"Street No 1",
"Educational Area",
1212,
"4156213754"
);
OnlineShoppingFacade facade = new OnlineShoppingFacade();
facade.FinalizeOrder(orderDetails);
Console.ReadLine();
}
Below is the output which we get.
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)