The Facade design pattern provides a unified interface to a set of interfaces in a subsystem. This pattern defines a higher-level interface that makes the subsystem easier to use.
C# code examples of the Facade design pattern is provided in 3 forms:
A visualization of the classes and objects participating in this pattern.
The classes and objects participating in this pattern include:
MortgageApplication
)
Bank, Credit, Loan
)
This structural code demonstrates the Facade pattern which provides a simplified and uniform interface to a large subsystem of classes.
using System;
namespace Facade.Structural
{
/// <summary>
/// Facade Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Subsystem ClassA' class
/// </summary>
public class SubSystemOne
{
public void MethodOne()
{
Console.WriteLine(" SubSystemOne Method");
}
}
/// <summary>
/// The 'Subsystem ClassB' class
/// </summary>
public class SubSystemTwo
{
public void MethodTwo()
{
Console.WriteLine(" SubSystemTwo Method");
}
}
/// <summary>
/// The 'Subsystem ClassC' class
/// </summary>
public class SubSystemThree
{
public void MethodThree()
{
Console.WriteLine(" SubSystemThree Method");
}
}
/// <summary>
/// The 'Subsystem ClassD' class
/// </summary>
public class SubSystemFour
{
public void MethodFour()
{
Console.WriteLine(" SubSystemFour Method");
}
}
/// <summary>
/// The 'Facade' class
/// </summary>
public class Facade
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public Facade()
{
one = new SubSystemOne();
two = new SubSystemTwo();
three = new SubSystemThree();
four = new SubSystemFour();
}
public void MethodA()
{
Console.WriteLine("\nMethodA() ---- ");
one.MethodOne();
two.MethodTwo();
four.MethodFour();
}
public void MethodB()
{
Console.WriteLine("\nMethodB() ---- ");
two.MethodTwo();
three.MethodThree();
}
}
}
This real-world code demonstrates the Facade pattern as a MortgageApplication object which provides a simplified interface to a large subsystem of classes measuring the creditworthiness of an applicant.
using System;
namespace Facade.RealWorld
{
/// <summary>
/// Facade Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// 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>
public class Bank
{
public bool HasSufficientSavings(Customer c, int amount)
{
Console.WriteLine("Check bank for " + c.Name);
return true;
}
}
/// <summary>
/// The 'Subsystem ClassB' class
/// </summary>
public class Credit
{
public bool HasGoodCredit(Customer c)
{
Console.WriteLine("Check credit for " + c.Name);
return true;
}
}
/// <summary>
/// The 'Subsystem ClassC' class
/// </summary>
public class Loan
{
public bool HasNoBadLoans(Customer c)
{
Console.WriteLine("Check loans for " + c.Name);
return true;
}
}
/// <summary>
/// Customer class
/// </summary>
public class Customer
{
private string name;
// Constructor
public Customer(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
}
/// <summary>
/// The 'Facade' class
/// </summary>
public class Mortgage
{
Bank bank = new Bank();
Loan loan = new Loan();
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;
}
}
}
The .NET optimized code demonstrates the same code as above but uses
more modern C# and .NET features.
Here is an elegant C# Facade solution.
namespace Facade.NetOptimized;
using static System.Console;
/// <summary>
/// Facade Design Pattern
/// </summary>
public class Program
{
static void Main()
{
// Facade
var mortgage = new Mortgage();
// Evaluate mortgage eligibility for customer
var customer = new Customer("Ann McKinsey");
bool eligible = mortgage.IsEligible(customer, 125000);
string result = eligible ? "Approved" : "Rejected";
WriteLine($"\n{customer.Name} has been {result}");
// Wait for user
ReadKey();
}
}
/// <summary>
/// The 'Subsystem ClassA' class
/// </summary>
public class Bank
{
public bool HasSufficientSavings(Customer c, int amount)
{
WriteLine($"Check bank for {c.Name}");
return true;
}
}
/// <summary>
/// The 'Subsystem ClassB' class
/// </summary>
public class Credit
{
public bool HasGoodCredit(Customer c)
{
WriteLine($"Check credit for {c.Name}");
return true;
}
}
/// <summary>
/// The 'Subsystem ClassC' class
/// </summary>
public class Loan
{
public bool HasNoBadLoans(Customer c)
{
WriteLine($"Check loans for {c.Name}");
return true;
}
}
/// <summary>
/// The 'Facade' class
/// </summary>
public class Mortgage
{
private readonly Bank bank = new();
private readonly Loan loan = new();
private readonly Credit credit = new();
public bool IsEligible(Customer cust, int amount)
{
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;
}
}
/// <summary>
/// Customer class
/// </summary>
public record Customer(string Name);