意图:希望简化原有系统的使用方式,需要定义自己的接口
问题:只需要使用某个复杂系统的子集,或者需要以一种特殊的方式与系统交互
解决方案:Facade为原有系统的客户提供一个新的接口,有可能减少客户所需要处理的对象数量
参与者与协作 者:为客户提供了一个简化接口,使用系统容易使用
效果:Facade模式简化了对所需要子系统的使用过程。但是,由于Facade并不完整,因此客户可能无法使用某些功能。子系统中的类不知道Facade的存在,也不会保存其引用。
实现 :定义一个具备所需要接口的新类,让新类使用原有的系统
附注:如果除了使用系统原有功能之外,还需要提供一些新功能,则可以为Facade类增加新的功能,这仍然是Facade模式。
Facade模式可以用来 隐藏或封装系统,可以在其中跟踪系统的使用情况或者改换系统。
Facade模式的使用十分的广泛,例如PHP的DAO层就是一个Facade,封装了对数据库的访问接口,应用不需要自己去处理数据库的各处底层处理。此外现实生活中,银行窗口就是银行复杂系统的一个Facade。
using System;
namespace Facade
{
/// <summary>
/// MainApp startup class for Real-World
/// Facade Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Facade
Mortgage mortgage = new Mortgage();
// Evaluate mortgage eligibility for customer
Customer customer = new Customer("Ann McKinsey");
bool eligible = mortgage.IsEligible(customer, 125000);
Console.WriteLine("\n" + customer.Name +
" has been " + (eligible ? "Approved" : "Rejected"));
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Subsystem ClassA' class
/// </summary>
class Bank
{
public bool HasSufficientSavings(Customer c, int amount)
{
Console.WriteLine("Check bank for " + c.Name);
return true;
}
}
/// <summary>
/// The 'Subsystem ClassB' class
/// </summary>
class Credit
{
public bool HasGoodCredit(Customer c)
{
Console.WriteLine("Check credit for " + c.Name);
return true;
}
}
/// <summary>
/// The 'Subsystem ClassC' class
/// </summary>
class Loan
{
public bool HasNoBadLoans(Customer c)
{
Console.WriteLine("Check loans for " + c.Name);
return true;
}
}
/// <summary>
/// Customer class
/// </summary>
class Customer
{
private string _name;
// Constructor
public Customer(string name)
{
this._name = name;
}
// Gets the name
public string Name
{
get { return _name; }
}
}
/// <summary>
/// The 'Facade' class
/// </summary>
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 eligible = true;
// Check creditworthyness of applicant
if (!_bank.HasSufficientSavings(cust, amount))
{
eligible = false;
}
else if (!_loan.HasNoBadLoans(cust))
{
eligible = false;
}
else if (!_credit.HasGoodCredit(cust))
{
eligible = false;
}
return eligible;
}
}
}
在上面的例子中Mortgage(借贷)是一个银行系统的Facade,它向用户隐藏了系统后台的各个类,如存款、信用、不良欠款等信息,只向外界提供一个判断用户是否拥有资质的接口,一方面减化了对系统的使用,另一方面也对用户和系统内部的多个类进行了解耦。