A Facade is a structural design pattern providing a simplified interface to a larger code, such as a library or complex class. In this article, I will write about the Facade Design Pattern in C#.
What is a facade design pattern?
The Facade design pattern encapsulates the complex logic and provides a simplified API to the end user. Often, a seemingly simple operation may contain quite complex code, hidden in the background, and just a simple method is exposed to the public. That method may use a lot of the complex code itself, but the end user doesnโt know about it. The exposed public API acts like a Facade behind which, the complex logic is hidden. The Facade is represented by the following UML diagram:
Example with C#
Imagine you are working on an application for online ticket purchases for different events. Your Facade can expose the BuyTicket method, which in the background is using a lot of other services for printing the ticket, accepting the payment, and sending the ticket via email. But you donโt care about these services, you just need to buy your ticket, so they are hidden behind a Facade.
Letโs look at the following example:
public class TicketFacade
{
private const decimal RegularTicketPrice = 1000m;
private const decimal VIPTicketPrice = 2000m;
public void BuyTicket(PurchaseInfo purchaseInfo)
{
// 1. Set the seat as reserved
this.SetSeatStatus(purchaseInfo.SeatNumber, SeatStatus.Reserverd);
// 2. Process the payment
var paymentService = new PaymentService();
var price = this.GetPrice(purchaseInfo.TicketType);
bool isPaymentSuccessful = paymentService.ProcessCardPayment(price, purchaseInfo.PaymentInfo);
if (isPaymentSuccessful)
{
// 3. Generate reciept, ticket and invoice
var printService = new PrintService();
string reciept = printService.PrintReciept(price);
string ticket = printService.PrintTicket(price, purchaseInfo.BuyerInfo.Name, purchaseInfo.SeatNumber);
string invoice = string.Empty;
if (purchaseInfo.GenerateInvoice)
{
invoice = printService.PrintInvoice(price, purchaseInfo.BuyerInfo.Name);
}
// 4. Send the generated items via email to the buyer
var emailSenderService = new EmailSenderService();
emailSenderService.SendEmail(purchaseInfo.BuyerInfo.Email, reciept, ticket, invoice);
}
else
{
// If payment fails - unreserve the seat
this.SetSeatStatus(purchaseInfo.SeatNumber, SeatStatus.NotReserved);
}
}
private decimal GetPrice(TicketType ticketType)
{
var price = RegularTicketPrice;
if (ticketType == TicketType.VIP)
price = VIPTicketPrice;
return price;
}
private void SetSeatStatus(int seatNumber, SeatStatus seatStatus)
{
// a Database call to mark the seleced seat as reserved/unrserved
}
}
The BuyTicket method accepts purchase information, needed for the online purchase. To buy the ticket you perform the following logic:
- Reserve the seat, so that no one else can select it
- Call the payment service and process a request to the bank:
internal class PaymentService
{
internal bool ProcessCardPayment(decimal price, PaymentInfo paymentInfo)
{
var result = false;
using (var client = new HttpClient())
{
// process payment request to the bank
}
return result;
}
}
public class PaymentInfo
{
public string CardNumber { get; set; }
public DateTime CardExpirationDate { get; set; }
public string CardSecurityCode { get; set; }
}
- If the payment is successful โ call the print service and generate a receipt and a ticket:
internal class PrintService
{
internal string PrintReciept(decimal price)
{
var result = string.Empty;
// generate the reciept
return result;
}
internal string PrintTicket(decimal price, string buyerName, int seatNumber)
{
var result = string.Empty;
// generate the ticket
return result;
}
internal string PrintInvoice(decimal price, string buyerName)
{
var result = string.Empty;
// generate the invoice
return result;
}
}
- If the customer has chosen to be invoiced โ generate an invoice
- And finally โ send the generated outcome to the email
- If the payment wasnโt successful mark the seat as not reserved
As you can see the BuyTicket method does a lot of stuff, to finalize the purchase, but this logic is hidden behind a facade. You just pass the purchase info and get your ticket via email. The user of the code doesnโt have to worry about, printing, payment, or anything else accompanying the purchase process.