Facade Pattern
Introduction:
Facade is a structural design pattern. The objective of the facade design pattern is to provide the simple interface to a complex subsystem. Wraps a complicated sub system with a simple interface. It promotes decoupling subsystem from its clients . On the other hand, facade is the only access point for the subsystem.
when to use,
A segment of the client community needs a simplified interface to the overall functionality of a complex subsystem.
How to use,
- Identify a simpler, unified interface for the subsystem or component.
- Design a “wrapper” class that encapsulates the subsystem.
- The facade/wrapper captures the complexity and collaborations of the component, and delegates to the appropriate methods.
- The client uses (is coupled to) the Façade only.
- Consider whether additional Facades would add value.
How Facade is different from other similar patterns,
Adapter vs Facade:
Facade provides a new interface, whereas adapter uses an existing interfaces (that means it make two existing interfaces to work together).
Mediator vs Facade:
Mediator centralizes communications between objects. It routinely adds value, and it is known/referenced by the colleagues objects. In contrast, facade defines a simpler interface to a subsystem, it doesn't add any functionality. It isn't known by the subsystem classes.
Mediator centralizes communications between objects. It routinely adds value, and it is known/referenced by the colleagues objects. In contrast, facade defines a simpler interface to a subsystem, it doesn't add any functionality. It isn't known by the subsystem classes.
Example:
Design a customer service representative. The customer calls to a customer service representative to place a order from catalog. Customer service representative acts as a facade and providing interface for order placing system, billing system, delivery system.
Implementation:
Sourcecode: https://github.com/krishnaKSA/design_patterns_cplusplus/blob/main/FacadePattern/FacadePattern.hpp
UML Class diagram:
//Order class
class Order
{
public:
void placeOrder()
{
cout<<"Order::order placed "<<endl;
}
};
//Payment class
class Payment
{
public:
void payBill()
{
cout<<"Payment::Payment done "<<endl;
}
};
//Delivery class
class Delivery
{
public:
void deliverOrder()
{
cout<<"Delivery::Delivery completed "<<endl;
}
};
Facade class:
//Facade class
class Facade
{
private:
//Facade holds the objects of subsystems
Order *order_obj;
Payment *payment_obj;
Delivery *delivery_obj;
public:
Facade(Order* oObj=nullptr, Payment* pObj=nullptr, Delivery* dObj=nullptr)
{
order_obj = oObj;
payment_obj = pObj;
delivery_obj = dObj;
}
//customer service function
void customerService()
{
bool bRetValue = false;
if(nullptr != order_obj)
{
order_obj->placeOrder();
if(nullptr != payment_obj)
{
payment_obj->payBill();
if(nullptr != delivery_obj)
{
delivery_obj->deliverOrder();
bRetValue = true;
}
}
}
if(!bRetValue)
{
cout<<"Facade::CustomerService :: Couldn't able to place the order !!!"<<endl;
}
else
{
cout<<"Facade::CustomerService :: Order placed successfully !!!"<<endl;
}
}
};
Client code:
void testFacadePattern()
{
Facade* obj = new Facade(new Order, new Payment, new Delivery);
obj->customerService();
}