The facade design pattern allows us, to provide a simplified interface from multiple class libraries. It provides a simple interface that hides the complexity of the class libraries being used.
UML Class diagram
For example, if the client code needs to access three different class libraries for a single functionality, instead of having the client code accessing those 3 class libraries, we can just create another class, that calls the required class libraries and have the client access only the class that you have created. The result is a simplified interface for the client and the client will not need to know the details of the actual (three) class libraries.
Real World Examples for Facade Pattern A MortgageApplication object, which provides a simplified interface to a large subsystem of classes measuring the credit worthiness of an applicant.
Implementation of above example in C#.Net
Create Customer class,
Create subsystem1 (Library1 from class diagram),
Create subsystem2 (Library2 from class diagram),
Create subsystem3 (Library3 from class diagram),
Now, create a Façade class,
Create a client to use above implemented façade class (Mortgage),
Output
test customer applies for $2,000,000.00 loan
Check bank for test customer
Check bad loans for test customer
Check credit for test customer
'test customer' has been Approved
Common mistakes while implementing facade pattern
In my experience the common mistakes I have seen are,
UML Class diagram
For example, if the client code needs to access three different class libraries for a single functionality, instead of having the client code accessing those 3 class libraries, we can just create another class, that calls the required class libraries and have the client access only the class that you have created. The result is a simplified interface for the client and the client will not need to know the details of the actual (three) class libraries.
Real World Examples for Facade Pattern A MortgageApplication object, which provides a simplified interface to a large subsystem of classes measuring the credit worthiness of an applicant.
Implementation of above example in C#.Net
Create Customer class,
public class Customer
{
private string _name;
public Customer(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
}
}
Create subsystem1 (Library1 from class diagram),
namespace DesignPatterns.Library1
{
public class Credit
{
public bool HasGoodCredit(Customer c)
{
Console.WriteLine("Check credit for " + c.Name);
return true;
}
}
}
Create subsystem2 (Library2 from class diagram),
namespace DesignPatterns.Library2
{
public class Bank
{
public bool HasSufficientSavings(Customer c, int amount)
{
Console.WriteLine("Check bank for " + c.Name);
return true;
}
}
}
Create subsystem3 (Library3 from class diagram),
namespace DesignPatterns.Library3
{
public class Loan
{
public bool HasBadLoans(Customer c)
{
Console.WriteLine("Check bad loans for " + c.Name);
return false;
}
}
}
Now, create a Façade class,
namespace DesignPatterns.Facade
{
public class Mortgage
{
private Bank _bank = new Bank();
private Loan _loan = new Loan();
private Credit _credit = new Credit();
public bool IsEligible(Customer cust, int amount)
{
Console.WriteLine("{0} applies for {1:C} loan\n", cust.Name, amount);
bool isEligible = true;
// Check creditworthyness of applicant
if (!_bank.HasSufficientSavings(cust, amount))
isEligible = false;
else if (_loan.HasBadLoans(cust))
isEligible = false;
else if (!_credit.HasGoodCredit(cust))
isEligible = false;
return isEligible;
}
}
}
Create a client to use above implemented façade class (Mortgage),
private void btnFacade_Click(object sender, EventArgs e)
{
// Facade class
Mortgage mortgage = new Mortgage();
// Evaluate mortgage eligibility of customer
Customer customer = new Customer("test customer");
bool eligible = mortgage.IsEligible(customer, 2000000);
Console.WriteLine("\n'" + customer.Name + "' has been " + (eligible ? "Approved" : "Rejected"));
}
Output
test customer applies for $2,000,000.00 loan
Check bank for test customer
Check bad loans for test customer
Check credit for test customer
'test customer' has been Approved
Common mistakes while implementing facade pattern
In my experience the common mistakes I have seen are,
- Just for the sake of introducing a facade layer developers tend to create additional classes. Layered architecture is good, but assesses the need for every layer.
- Methods in facade layer have only one or two lines which calls the other components. If facade is going to be so simple, it invalidates its purpose and clients can directly do that by themselves.
- A controller is not a facade.
- Facade is ‘not’ a layer that imposes security and hides important data and implementation.
- Don’t create a facade layer in advance. If you feel that in future the subsystem is going to evolve and become complicated to defend that do not create a stub class and name it a facade. After the subsystem has become complex you can implement the facade design pattern.
- Subsystems are not aware of facade and there should be no reference for facade in subsystems.
- Makes a software library easier to use, understand and test, since the facade has convenient methods for common tasks
- Makes code that uses the library more readable, for the same reason
- Reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system
- Wrap a poorly-designed collection of APIs with a single well-designed API.