In this article, we are about to cover another design pattern in C#, this time a structural one. That pattern is the Facade Pattern.

The source code is available at the Facade Design Pattern GitHub Repository.

For the complete list of articles from this series check out C# Design Patterns.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

What is a Facade Pattern?

As the name suggests, it represents a “facade” for the end-user to simplify the usage of the subsystems that are poorly designed and/or too complicated by hiding their implementation details. It also comes in handy when working with complex libraries and APIs.

A Facade Pattern is represented by a single-class interface that is simple, easy to read and use, without the trouble of changing the subsystems themselves. However, we must be careful since limiting the usage of the subsystem’s functionalities may not be enough for the power-users.

Facade Pattern Example

As an example for explaining the Facade Pattern better, we are going to describe the workflow of ordering food online.

Let’s say we have a list of restaurants. We open the restaurant’s page, find the dish that we like and add it to the cart. We do it as many times as we want and complete the order. When we submit the order, we get an order confirmation along with the price of the order.

First, let’s create a class named Order that will represent the order coming from the User:

public class Order
{
    public string DishName { get; set; }
    public double DishPrice { get; set; }
    public string User { get; set; }
    public string ShippingAddress { get; set; }
    public double ShippingPrice { get; set; }

    public override string ToString()
    {
        return string.Format("User {0} ordered {1}. The full price is {2} dollars.",
            User, DishName, DishPrice + ShippingPrice);
    }
}

Furthermore, we have to create two more classes – an online restaurant and a shipping service. The OnlineRestaurant class provides methods for adding orders to the cart:

public class OnlineRestaurant
{
    private readonly List<Order> _cart;

    public OnlineRestaurant()
    {
        _cart = new List<Order>();
    }

    public void AddOrderToCart(Order order)
    {
        _cart.Add(order);
    }

    public void CompleteOrders()
    {
        Console.WriteLine("Orders completed. Dispatch in progress...");
    }
}

On the other hand, the ShippingService class accepts the order and ships them to the address stored in the ShippingAddress property inside the Order class. The ShippingService also calculates the shipping expenses and displays them to the user:

public class ShippingService
{
    private Order _order;

    public void AcceptOrder(Order order)
    {
        _order = order;
    }

    public void CalculateShippingExpenses()
    {
        _order.ShippingPrice = 15.5;
    }

    public void ShipOrder()
    {
        Console.WriteLine(_order.ToString());
        Console.WriteLine("Order is being shipped to {0}...", _order.ShippingAddress);
    }
}

In the end, we are incorporating the entire logic into the Main class to represent the workflow of ordering food online:

class Program
{
    static void Main(string[] args)
    {
        var restaurant = new OnlineRestaurant();
        var shippingService = new ShippingService();

        var chickenOrder = new Order() { DishName = "Chicken with rice", DishPrice = 20.0, User = "User1", ShippingAddress = "Random street 123" };
        var sushiOrder = new Order() { DishName = "Sushi", DishPrice = 52.0, User = "User2", ShippingAddress = "More random street 321" };

        restaurant.AddOrderToCart(chickenOrder);
        restaurant.AddOrderToCart(sushiOrder);
        restaurant.CompleteOrders();

        shippingService.AcceptOrder(chickenOrder);
        shippingService.CalculateShippingExpenses();
        shippingService.ShipOrder();

        shippingService.AcceptOrder(sushiOrder);
        shippingService.CalculateShippingExpenses();
        shippingService.ShipOrder();

        Console.ReadLine();
    }
}

The result of the current implementation of the Main class is:

main output 1 without facade

Note: We assume that the orders are coming from the outside and that’s why we created them inside the Main class. This is optional, of course, for more complicated systems this would also be a part of some service.

Now, for those of you who are wondering:

“Why is this wrong?”

Continue reading.

Looking at the Main class and all the steps we’ve implemented, we can see a lot of code in one single class. Since we tend to make things easier to read and less complicated, we have to make some adjustments.

And that’s where the Facade Pattern steps in.

Facade Pattern Implementation

One of the goals of the Facade Pattern is to hide the implementation details which indicates that having everything in the Main class doesn’t do the work. It is too much unnecessary information, therefore, we would like it better somewhere else.

That said, we are going to create another class called Facade. The Facade class will act as a “middleware” between the User and the complexity of the system without changing the business logic:

public class Facade
{
    private readonly OnlineRestaurant _restaurant;
    private readonly ShippingService _shippingService;

    public Facade(OnlineRestaurant restaurant, ShippingService shippingService)
    {
        _restaurant = restaurant;
        _shippingService = shippingService;
    }

    public void OrderFood(List<Order> orders)
    {
        foreach (var order in orders)
        {
            _restaurant.AddOrderToCart(order);
        }

        _restaurant.CompleteOrders();

        foreach (var order in orders)
        {
            _shippingService.AcceptOrder(order);
            _shippingService.CalculateShippingExpenses();
            _shippingService.ShipOrder();
        }
    }
}

Since we’ve moved the implementation logic to the Facade class, we can simplify the Main class:

class Program
{
    static void Main(string[] args)
    {
        var restaurant = new OnlineRestaurant();
        var shippingService = new ShippingService();

        var facade = new Facade(restaurant, shippingService);

        var chickenOrder = new Order() { DishName = "Chicken with rice", DishPrice = 20.0, User = "User1", ShippingAddress = "Random street 123" };
        var sushiOrder = new Order() { DishName = "Sushi", DishPrice = 52.0, User = "User2", ShippingAddress = "More random street 321" };

        facade.OrderFood(new List<Order>() { chickenOrder, sushiOrder });

        Console.ReadLine();
    }
}

When we run the code, we can see the exact output:

main output 2 facade

This means we have successfully freed the user of the unnecessary pressure of knowing all the required steps for the food to arrive.

Note: in this example, we passed the OnlineRestaurant and the ShippingService to the Facade, assuming that they are already created. However, they can also be instantiated inside the Facadeitself.

Conclusion

So, we have seen how the Facade Pattern can assist us in making the client’s lives easier. Now, we are ready to embrace the complex implementations as is. And last but not least, in certain situations, using this pattern requires carefulness. It can limit the user’s abilities to make use of the full potential of the application or library that we’re trying to simplify.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!