Featured Post

Trie implementation in C

Facade design pattern implementation in C++



Facade means the exterior of any object in general. Facade Design Pattern provides similar functionality as well. It provides a simple interface to a complex system. Just as we can not tell from the exterior of a building what lies inside it, Facade design pattern provides an interface which hides the internal complexity of a system. It only exposes the desired interfaces which have to be used by a client. It can be only a small subsystem of the complex system as the client may not need all the functionality of the complex system. Also it could modify the interfaces as well to provide the complete functionality of the system.

Facade Design Pattern
Facade Design Pattern

 For our implementation of the Facade Design Pattern, we have chosen example of Online Shopping model. The following diagram represents the relationships and flow between the classes.

Class Diagram for below example
The example works like this. OnlineShoppingFacade is the interface which is exposed to the customers (us). It's just like any portal like Flipkart, Amazon or eBay. Now we do not know what the heck is going behind those websites. All we know is that we have just placed an order and we will get a delivery after a certain period of time. Of course there is a status tracker something like this




But still the intricacies behind the process is hidden away from us. This is the Facade for the Online Shopping Portal.

Below is a simplistic implementation just to demo how Facade Design Pattern works using a C++ example.

Facade Design Pattern Implementation(C++)

Update(5th Nov 2014): The code is updated to work on linux platform as well.



#include <iostream>
#include <string>
#ifdef _WIN32
#include <windows.h>
#elif defined __linux__
#include <unistd.h>
#endif

/* Uncomment below line to enable debug logs */
/* #define DEBUG */
 
std::string _stateToStrCourier[]   = { "Received", "VerifyReachbility", "AssignPerson", 
                                       "DispatchPackage", "GetDeliveryConfirmation", "Complete"};
std::string _stateToStrVendor[]    = { "Received", "VerifyInventory", "GetItemFromWareHouse", 
                                       "PackItem", "ContactCourier", "Complete"};
std::string _stateToStrOrderTeam[] = { "Received", "VerifyPayment", "ContactVendor", "Complete"};

void mySleep(unsigned int millisecs)
{
#ifdef _WIN32
 Sleep(millisecs);
#elif defined __linux__
 usleep(1000 * millisecs);
#endif
}

class Courier
{
public:
 void submitRequestToCourier()
 {
  _state = 0;
 }
 bool checkStatus()
 {
#ifdef DEBUG
  std::cout<<"Courier: Current State: "<<_stateToStrCourier[_state]<< std::endl;
#endif
  mySleep(500); /* Do some useful work here */

  _state++;
  if (_state == Complete)
   return 1;
  return 0;
 }
private:
 enum States
 {
  Received, VerifyReachbility, AssignPerson, DispatchPackage, GetDeliveryConfirmation, Complete
 };
 int _state;
};
 
class Vendor
{
public:
 void submitRequestToVendor()
 {
  _state = 0;
 }
 bool checkStatus()
 {
#ifdef DEBUG
  std::cout<<"Vendor: Current State: "<<_stateToStrVendor[_state]<< std::endl;
#endif
  mySleep(500); /* Do some useful work here */

  _state++;
  if (_state == Complete)
   return 1;
  return 0;
 }
private:
 enum States
 {
  Received, VerifyInventory, GetItemFromWareHouse, PackItem, ContactCourier, Complete
 };
 int _state;
 
};
 
class OrderingTeam
{
public:
 void submitRequestToOrderTeam()
 {
  _state = 0;
 }
 bool checkStatus()
 {
#ifdef DEBUG
  std::cout<<"OrderingTeam: Current State: "<<_stateToStrOrderTeam[_state]<< std::endl;
#endif
  mySleep(500); /* Do some useful work here */ 
  _state++;
  if (_state == Complete)
   return 1;
  return 0;
 }
private:
 enum States
 {
  Received, VerifyPayment, ContactVendor, Complete
 };
 int _state;
};
 
class OnlineShoppingFacade
{
public:
 OnlineShoppingFacade()
 {
  _count = 0;
 }
 void submitRequest()
 {
  _state = 0;
 }
 bool checkStatus()
 {
  /* Item request has just been received */
  switch(_state)
  {
  case Received:
   _state++;
   /* Forward the job request to the ordering team */
   _order.submitRequestToOrderTeam();
   std::cout << "submitted to Order Team - " << _count <<
    " followups till now" << std::endl;
   break;
  case SubmittedToOrderTeam:
   /* If order team has completed verification, 
   place the request with vendor */
   if (_order.checkStatus())
   {
    _state++;
    _vendor.submitRequestToVendor();
    std::cout << "submitted to Vendor - " << _count <<
     " followups till now" << std::endl;
   }
   break;
  case SubmittedToVendor:
   /* If vendor has packed the item, forward it to courier */
   if (_vendor.checkStatus())
   {
    _state++;
    _courier.submitRequestToCourier();
    std::cout << "submitted to Courier - " << _count <<
     " followups till now" << std::endl;
   }
   break;
  case SubmittedToCourier:
   /* If package is delivered, order is complete */
   if (_courier.checkStatus())
    return 1;
  default:
   break;
  }
 
  _count++;
 
  /* The order is not complete */
  return 0;
 }
 int numFUPs()
 
 {
  return _count;
 }
private:
 enum States
 {
  Received, SubmittedToOrderTeam, SubmittedToVendor, SubmittedToCourier
 };
 
 int _state;
 int _count;
 
 OrderingTeam _order;
 Vendor _vendor;
 Courier _courier;
};
 
int main()
{
 OnlineShoppingFacade onlinereq;
 
 onlinereq.submitRequest();
 
 /* Keep checking until order is complete */
 while (!onlinereq.checkStatus());
 
 std::cout << "Order completed after " << onlinereq.numFUPs() << 
  " followups" << std::endl;
}


Comments

  1. This design pattern is very important for keeping project maintainable.

    ReplyDelete
  2. Facade simplifies a huge project. Might not be visible when projects are small

    ReplyDelete
  3. Whenever u wanted to interact with Third Party Libraries as well as Platform libraries u need to stick with Facade Design Pattern.Like If u r connecting Ur Database through Platform API's then Facade will also comes into Picture.

    ReplyDelete
  4. Such a nice blog and i appreciate your all efforts about your thoughts. it's really good work. well done.
    Facade Engineer

    ReplyDelete

Post a Comment

Please post your valuable suggestions