Meet the Incredible, Unsung Hero: Facade Pattern C#


Do you ever feel like you are trying to be someone else? That is the feeling most of us have probably experienced at some point in our lives.

Similar to this, you often have a C# code that you want to represent as much simpler than it is. In those cases, you can use the Facade design pattern.

The Facade design pattern is a software design pattern that provides a unified interface to a set of classes, hiding their complexity from the user. The Facade design pattern is often used to improve the usability of a software library or framework.

In this article, you will learn about the Facade pattern and see how you can apply it in real-world scenarios. Read on if you want to know more about what facades are when you should use them, and how to implement them.

What is the C# Facade design pattern?

The Facade design pattern is a pattern that provides a simplified interface to a complex system. It makes a complex system easier to use. You can use the Facade design pattern when a system is too complex or difficult to understand. You can also use it when a system is difficult to change.

The Facade design pattern falls under the structural pattern.

Facade comes from the French word facade, which means “frontage” or “face”. Generally, a Facade means the exterior appearance of a building or any other form of representation.

What is the intention of the Facade Design Pattern?

Facade Pattern provides a unified interface to a set of classes in a subsystem. The primary intent of Facade is to make a more straightforward interface. For example, Facade routinely wraps multiple objects and could front-end a single complex object.

What problems does the facade pattern address?

When you have a complex subsystem that refers directly to many objects with entirely different interfaces or is dependent on these objects, this makes the implementation, adaptation, testing, and reuse of the clients particularly difficult for developers.

There is a fundamental violation of SOLID design principles here due to the tight coupling between the clients and the subsystem. Clients need to interact with multiple services implemented by subsystem classes. Due to their multiple interactions, there can be a lack of encapsulation of the internal structure of the subsystems.

When to use the Facade design pattern?

You can use the Facade pattern when the abstraction and implementations of a subsystem are tightly coupled. The Facade also decouples the code that uses the system from the details of the subsystems. That makes the system easier to modify in the future.

You can also use it when you need an entry point to each level of layered software or the system you created is very complex or difficult to understand.

Structural code to show the implementation of Facade design pattern in C#

To better understand this pattern, you can see the below UML diagram:

Let’s see the sample structural code:

public class Facade
{
    protected Subsystem1 _subsystem1;

    protected Subsystem2 _subsystem2;

    public Facade(Subsystem1 subsystem1, Subsystem2 subsystem2)
    {
        this._subsystem1 = subsystem1;
        this._subsystem2 = subsystem2;
    }
    public string Operation()
    {
        string result = "Facade initializes subsystems:\n";
        result += this._subsystem1.operation1();
        result += this._subsystem2.operation1();
        result += "Facade calls subsystems to execute the action:\n";
        result += this._subsystem1.operationN();
        result += this._subsystem2.operationZ();
        return result;
    }
}

public class Subsystem1
{
    public string operation1()
    {
        return "Subsystem1: Ready!\n";
    }

    public string operationN()
    {
        return "Subsystem1: Go!\n";
    }
}

public class Subsystem2
{
    public string operation1()
    {
        return "Subsystem2: Get ready!\n";
    }

    public string operationZ()
    {
        return "Subsystem2: Fire!\n";
    }
}


class Client
{
    public static void ClientCode(Facade facade)
    {
        Console.Write(facade.Operation());
    }
}

And the actual usage:

Subsystem1 subsystem1 = new Subsystem1();
Subsystem2 subsystem2 = new Subsystem2();
Facade facade = new Facade(subsystem1, subsystem2);
Client.ClientCode(facade);

The above code produces the following output:

Facade initializes subsystems:
Subsystem1: Ready!
Subsystem2: Get ready!
Facade calls subsystems to execute the action:
Subsystem1: Go!
Subsystem2: Fire!

An important point to remember is that the subsystem can accept requests directly from the Facade or the client. In any case, the Facade is another client of the subsystem and is not a part of the subsystem.

Facade design pattern – real-world example in C#

To illustrate how to use the Facade pattern, let’s take a real-world example of a restaurant. First, you can call the restaurant and order a burger or other food. Then the operator, on behalf of a restaurant, gives the voice interface, which is a facade for you. So now, you can order a Burger, and you need not worry about the complexity of preparing a Burger, like what all operations they perform or the temperature they will cook.

Now, let’s dive into the code. We start by defining the IBurger interface.

public interface IBurger
{
    void GetVegetarianBurger();
    void GetRegularBurger();
}

This is a burger provider class that will get burgers for their clients. The methods can have other private methods which the client is not bothered about.

public class BurgerProvider : IBurger
{
    public void GetRegularBurger()
    {
        GetRegularBurgerIngredients();
        Console.WriteLine("Getting regular burger.");
    }
    public void GetVegetarianBurger()
    {
        Console.WriteLine("Getting vegetarian burger.");
    }
    private void GetRegularBurgerIngredients()
    {
        Console.WriteLine("Getting regular burger ingredients.");
    }
}

Similarly, this is the interface specification for the buns.

public interface BurgerBun
{
    void GetPlainBun();
    void GetSeasmeSeedBun();
}

public class BunProvider : BurgerBun
{
    public void GetPlainBun()
    {
        Console.WriteLine("Getting plain bun.");
    }
    public void GetSeasmeSeedBun()
    {
        Console.WriteLine("Getting seasme seed bun.");
    }
}

At last, the Restaurant Facade class will be used by the client to order different Burgers or buns.

public class RestaurantFacade
{
    private IBurger _burgerProvider;
    private BurgerBun _bunProvider;
    public RestaurantFacade()
    {
        _burgerProvider = new BurgerProvider();
        _bunProvider = new BunProvider();
    }
    public void GetReguralBurger()
    {
        _bunProvider.GetPlainBun();
        _burgerProvider.GetRegularBurger();
    }
    public void GetVegetarianBurger()
    {
        _bunProvider.GetSeasmeSeedBun();
        _burgerProvider.GetVegetarianBurger();
    }
}

Benefits of using the Facade design pattern

The few benefits of the Facade design pattern are:

  • The Facade hides the underlying software subsystems and thereby reduces the complexity of these systems.
  • It promotes loose coupling.
  • Due to the low interdependence of the individual components, changes are convenient and possible at any time. Because of loose coupling, a subsystem is easier to expand.
  • If a client is dependent on certain subsystem classes, this can also be granted in the facade pattern model.
  • The software becomes more flexible and easily expandable.

What are related patterns to the Facade design pattern?

The Mediator pattern is similar to the Facade as it combines different existing functionality to create a new one. However, the Mediator is a behavioral pattern, and it describes the way the objects communicate.

The difference between the Mediator and Facade patterns is: The Mediator defines how different objects interact with each other. The objects are aware of the Mediator. The Facade pattern provides an interface for working with a complex subsystem. The subsystem’s classes are not aware of the Facade.

The Facade can often be implemented as a Singleton object. That object serves as the application’s main access point. It allows users to access the application’s core objects (managers, controllers, and so on), and you can execute common operations. Such a facade is often responsible for instantiating and initializing the main objects and getting the application up and running.

What is the difference between Factory Method and Facade patterns?

The Factory Method design pattern is a creational design pattern that uses factory methods to create objects. You use it to encapsulate object creation logic in a class, making it easy to create new objects. You can use the Factory Method when an object needs to be created, but the exact type is not known at compile time.

The main difference between the Factory Method and Facade patterns is that the Factory Method creates a new object. In contrast, the Facade pattern provides a simplified interface to an existing object.

What’s the difference between Abstract Factory and Facade patterns?

The Abstract Factory design pattern is a creational design pattern that allows for creating objects that belong to a common family without specifying the concrete classes of those objects.

The Abstract Factory defines an interface for creating objects but leaves the actual implementation details up to the concrete subclass. On the other hand, the Facade provides a simplified interface to a complex subsystem.

If you want to learn about the importance of the Abstract Factory pattern, check out the separate article about it.

Is the Facade an anti-pattern?

In software development, an anti-pattern is a solution to a recurring problem that is usually ineffective and risks being highly counterproductive. Anti-patterns are the polar opposite of design patterns. Unfortunately, they are also a frequent way to solve a problem.

The Facade design pattern is not an anti-pattern. On the contrary, it’s a perfectly valid and useful design pattern that can make code more readable and maintainable. It’s often used in frameworks to provide a more straightforward interface to complex code.

Conclusion

The Facade design pattern is an excellent way to decouple your code and make it more maintainable. If you need to expose the functionality of a complex system to third parties, the Facade pattern is a good choice.

There are three main reasons for using the Facade design pattern:

  1. It encapsulates the domain logic’s complexity into a separate class that is unaware of the implementation details.
  2. It provides a uniform interface for the client code.
  3. It hides the implementation of the underlying data structures.

Recent Posts