Facade

Intent

Provide a simplified interface to a complex system of classes, library or framework.

Problem

Imagine the code that has to work with a large set of objects of some complex library or framework. You have to manually initialize all these objects, keep track of the dependencies, correct order and so on.

In the end, the business logic of your classes becomes tightly coupled to the implementation details of third party library. Such code is pretty hard to comprehend and maintain.

Solution

The facade is a class that provides a simple interface to a complex subsystem containing dozens of classes. The facade may have limited functionality in comparison to working with subsystem directly. However, it includes only those features that clients really care about.

Facade is handy when you use a sophisticated library with a lot of moving parts, but you need only a fraction of its functionality.

For instance, an app that uploads short videos with cats to the Youtube could use a professional video conversion library. But all that it really needs is a class with a single method encode(filename, format). After creating such class, you get your first facade.

Real-World Analogy

Placing orders by phone

When you call a shop to place a phone order, an operator is your facade to all services and departments of the shop. He or she provides a simple interface to the ordering system, payments, and delivery services.

Structure

Facade pattern structure
  1. Facade provides convenient access to a particular part of the subsystem's functionality. It knows where to direct the client request and how to prepare all the moving parts.

  2. Additional facades can be created to divide responsibilities and prevent growing an original facade into yet another complex structure. Additional facades can be used either by Clients or other Facades.

  3. Complex subsystem contains dozens of classes. To make them do something meaningful, you have to know their implementation details, the initialization order and lots of other things.

    Note that subsystem classes are not aware of the Facade's existence and work with each other directly.

  4. Client uses Facade instead of calling the Subsystem objects directly.

Pseudocode

In this examples, the Facade simplifies interaction with a complex video conversion framework. The Facade is a single class with a single public method that handles all the complexity of configuring the right classes of the framework and retrieving result in a correct format.

This way the Facade pattern shields client code from the complexity, keeps it clean and lean.

// Some classes of a complex 3rd-party video conversion framework. We don't
// control that code, therefore can't simplify it.

class VideoFile
// ...

class OggCompressionCodec
// ...

class MPEG4CompressionCodec
// ...

class CodecFactory
// ...

class BitrateReader
// ...

class AudioMixer
// ...


// To defeat the complexity, we create a Facade class, which hides all of the
// framework's complexity behind a simple interface. It is a trade-off between
// functionality and simplicity.
class VideoConvertor is
    method convertVideo(filename, format):File is
        file = new VideoFile(filename)
        sourceCodec = new CodecFactory.extract(file)
        if (format == "mp4")
          distinationCodec = new MPEG4CompressionCodec()
        else
          distinationCodec = new OggCompressionCodec()
        buffer = BitrateReader.read(filename, sourceCodec);
        result = BitrateReader.convert(buffer, distinationCodec);
        result = (new AudioMixer()).fix(result);
        return new File(result)

// Application classes don't depend on a billion classes provided by the complex
// framework. Also, if you happen to decide to switch framework, you will only
// need to rewrite the facade class.
class Application is
    method main() is
        convertor = new VideoConvertor();
        mp4video = convertor.convertVideo("youtubevideo.ogg", "mp4")

Applicability

When you need to have a simple but limited interface to a complex subsystem.

Often subsystems get more complex over time. Even applying design patterns often leads to creating more classes. The subsystem may become more flexible and easier to reuse in different contexts, but the amount of boilerplate code it requires also grows. The Facade attempts to fix it by providing access to a fraction of a subsystem that fits most client needs.

When you want to structure a subsystem into layers.

Create facades to define the entry points to each level of a subsystem. If multiple subsystems depend on each other, you can limit the coupling by requiring subsystems to communicate only through facades.

How to Implement

  1. Check whether it is possible to simplify the interface of communication with a complex subsystem.

    You're on the right track if this interface will make client free of subsystem dependency.

  2. Create a facade class and describe this interface in it. It has to direct client calls to the appropriate objects of the subsystem. Facade should take care of correct subsystem initialization. Usually, this code lives inside the facade constructor. Lazy initialization may also be useful.

  3. You'll get a full benefit if client code would only work with the facade. In this case, the client will be protected from all changes in the subsystem code. For example, when a library's code gets updated, you'll only need to fix a facade.

  4. If the facade becomes monstrous, think of extracting new refined facades.

Pros and Cons

  • Isolates clients from subsystem components.
  • Minimizes coupling between client code and subsystem.
  • Facade risks becoming a "god object", coupled to all application classes.

Relations with Other Patterns

  • Facade defines a new interface, whereas Adapter reuses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.

  • Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.

  • Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.

  • Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communications between colleague objects. It routinely "adds value", and it is known/referenced by the colleague objects. In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes.

  • Facade can be transformed into Singleton since most of the time single facade object is sufficient.

  • Facade is similar to Proxy in that it buffers a complex entity and also initializes it. Unlike the Facade, the Proxy pattern has the same interface as its service object, which makes them interchangeable.

Implementations in Different Programming Languages

Java