- A Facade is a class that provides an interface or medium (a set of methods and properties) that makes it easier for clients to use classes and objects in a complex subsystem**.**
- The intent of the Facade is to provide a high-level architectural interface that makes a subsystem or toolkit easy to use for the client.
- In a 3-tier application, the service layer, or Facade, hides the complexity of the business objects and their interactions.
- Another area where you use Facade patterns is in refactoring efforts.
- If you're dealing with a confusing or messy set of legacy classes that the client programmer should not see you hide it behind a Facade**.**
- An example of an Facade in .NET is System.Diagnostics.EventLog.
- It exposes a simple API to the client, whose only concern is creating the EventLog instance, setting and getting some properties, and writing events to the server’s event log.
- Complex operations, including opening and closing read-and-write handles are totally hidden from the client.
Participants
Facade
(MortgageFacade)
- Knows which subsystem classes are responsible for a request.
- Delegates client requests to appropriate subsystem objects.
Subsystem
Classes (Bank, Credit, Loan)
- Implement subsystem functionality.
- Handle work assigned by the
Facade
object.
var bank = new Bank();
var loan = new Loan();
var credit = new Credit();
MortgageFacade mortgage = new MortgageFacade(bank, loan, credit);
var eligible = mortgage.IsEligible("Customer Name", 125000);
public class Bank
{
public bool HasSufficientSavings(string customer, int amount) => true;
}
public class Credit
{
public bool HasGoodCredit(string customer) => true;
}
public class Loan
{
public bool HasNoBadLoans(string customer) => true;
}
public class MortgageFacade
{
private Bank _bank;
private Loan _loan;
private Credit _credit;
public MortgageFacade(Bank bank, Loan loan, Credit credit)
{
_bank = bank;
_loan = loan;
_credit = credit;
}
public bool IsEligible(string customer, int amount)
{
bool eligible = true;
if (!_bank.HasSufficientSavings(customer, amount))
eligible = false;
else if (!_loan.HasNoBadLoans(customer))
eligible = false;
else if (!_credit.HasGoodCredit(customer))
eligible = false;
return eligible;
}
}
Rules of Thumb
- Facade defines a new interface, whereas Adapter uses an old interface.
- Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.
- Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
- Mediator is similar to Facade in that it abstracts functionality of existing classes.
- Mediator abstracts/centralizes arbitrary communications between colleague objects.
- It routinely "adds value", and it is known/referenced by the colleague objects.
- In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes.
- Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
- Facade objects are often Singletons because only one Facade object is required.
- Adapter and Facade are both wrappers; but they are different kinds of wrappers.
- The intent of Facade is to produce a simpler interface, and the intent of Adapter is to design to an existing interface.
- While Facade routinely wraps multiple objects and Adapter wraps a single object; Facade could front-end a single complex object and Adapter could wrap several legacy objects.
- The difference between the Adapter pattern and the Facade pattern is that the Adapter wraps one class and the Facade may represent many classes?
- While most textbook examples show the adapter adapting one class, you may need to adapt many classes to provide the interface a client is coded to.
- Likewise, a Facade may provide a simplified interface to a single class with a very complex interface.
- The difference between the two is not in terms of how many classes they "wrap", it is in their intent.