Façade Pattern

Role

The role of the Façade pattern is to provide different high-level views of subsystems whose details are hidden from users. In general, the operations that might be desirable from a user's perspective could be made up of different selections of parts of the subsystems.

Illustration

Simple interfaces to complex subsystems abound in real life. They can be created to make frequent use of a system faster, or to differentiate between novices and power users. A good illustration is Amazon.com's 1-Click® system (Figure 4-4), which simplifies the process of ordering items for well-known customers. Normally, after selecting an item to purchase, an Amazon customer has to enter delivery and bank account details before the order is accepted. If these details are stored and the customer verifies her identity in some way, 1-Click takes that customer straight to the checkout. The customer's stored bank account details and selected delivery address are used for the purchase, thus considerably speeding up (and simplifying) the ordering process. Thus, the 1-Click option forms a façade to the fuller system underneath.

Façade pattern illustration—1-Click®

Figure 4-4. Façade pattern illustration—1-Click®

Design

Hiding detail is a key programming concept. What makes the Façade pattern different from, say, the Decorator or Adapter patterns is that the interface it builds up can be entirely new. It is not coupled to existing requirements, nor must it conform to existing interfaces. There can also be several façades built up around an existing set of subsystems. The term "subsystem" is used here deliberately; we are talking at a higher level than classes. See the UML diagram in Figure 4-5; it considers the subsystems to be grouped together, so they can interact in agreed ways to form the top-level operations.

Façade pattern UML diagram

Figure 4-5. Façade pattern UML diagram

The roles are:

Namespace 1

A library of subsystems

Subsystem

A class offering detailed operations

Façade

A class offering a few high-level operations as selections from the subsystems

Namespace 2

Where the client resides

Client

Calls the high-level operations in the Façade in Namespace 1

As shown in the UML diagram, the client's code does not make reference to the classes of the names of the subsystems; it only gets access to their operations via the Façade.

Implementation

The Façade pattern is simple to implement. It uses the C# concept of namespaces. Classes in namespaces have the facility to define accessibility as internal or public. If accessibility is defined as internal, the member is visible only in the assembly in which the namespace is compiled. In a very large system, the client's GUI will be in a different namespace from the library, so we can enforce the Façade. (Alternative implementations of the Façade pattern will be discussed shortly.)

In Example 4-5, the theory code comes from two files: Façade-Main.cs and Façade-Library.cs. Both have to be compiled with special directives so that library in Façade-Library.cs is recognized as a lib file and the client in Façade-Main.cs can reference it. These commands are:

// Compile the library
csc /t:library /out:FacadeLib.dll Facade-Library.cs

// Compile the main program
csc /r:FacadeLib.dll Facade-Main.cs

Tip

This process of compiling and using libraries is facilitated in environments such as Visual Studio.

The example mirrors the diagram in Figure 4-5. Three subsystems, implemented as classes, are inserted into the library. Facade is a static class that instantiates the three subsystems under the façade as objects called a, b, and c. Operations 1 and 2 then select combinations of methods from a, b, and c. For example, Operation1 will call two methods in a, one in b, and none in c. Thus, the Facade is a means of providing an interface to operations that should, on their own, remain hidden.

The client starts with a using statement that indicates it wants access to the public members in the FacadeLib namespace. Then it calls the Facade's two high-level operations. The output is shown below in Example 4-5.

Example 4-5. Façade pattern theory code

   using System;

      // Facade Pattern                 Judith Bishop  Dec 2006
      // Sets up a library of three systems, accessed through a
      // Facade of two operations
      // Compile with
      // csc /t:library /out:FacadeLib.dll Facade-Library.cs

    namespace Library {

        internal class SubsystemA {
          internal string A1(  ) {
              return "Subsystem A, Method A1\n";
          }
          internal string A2(  ) {
              return "Subsystem A, Method A2\n";
          }
        }

        internal class SubsystemB {
          internal string B1(  ) {
            return "Subsystem B, Method B1\n";
          }
        }

        internal class SubsystemC {
          internal string C1(  ) {
            return "Subsystem C, Method C1\n";
          }
        }
      }

   public static class Facade {
     static SubsystemA a = new SubsystemA(  );
     static SubsystemB b = new SubsystemB(  );
     static SubsystemC c = new SubsystemC(  );

     public static void Operation1(  ) {
       Console.WriteLine("Operation 1\n" +
           a.A1(  ) +
           a.A2(  ) +
           b.B1(  ));
    }

     public static void Operation2(  ) {
       Console.WriteLine("Operation 2\n" +
           b.B1(  ) +
           c.C1(  ));
     }
   }

     // ============= Different compilation

    using System;
    using FacadeLib;

    // Compile with csc /r:FacadeLib.dll Facade-Main.cs

    class Client {
      static void Main (  ) {
        Facade.Operation1(  );
        Facade.Operation2(  );
      }
    }/* Output

 Operation 1
 Subsystem A, Method A1
 Subsystem A, Method A2
 Subsystem B, Method B1

 Operation 2
 Subsystem B, Method B1
 Subsystem C, Method C1
 */

Everything in the façade has to be public so that the Client, which is compiled into a different assembly, can access it. The classes all have the default internal visibility, limiting access to them to the assembly in which they were compiled (excluding the Client). As a test, if we try to let the Client instantiate any of the subsystems directly, we will get an error like the following:

SubsystemC x = new SubsystemC(  );
x.C1(  );Facade2Main.cs(12,3): error CS0122: 'FacadeLib.SubsystemC' is inaccessible
 due to its protection level

Façade Alternatives

Some alternative implementations of the Façade pattern are:

Transparent façades

The façade described in the preceding example is opaque, in that the subsystems cannot be accessed except via the Facade object. This requirement might be too stringent. Suppose some users want to get at the individual operations of particular subsystems. We can change all the internal modifiers to public, which will make the façade optional, or transparent. That is, as well as being able to go through the Facade, the client will be able to instantiate SubsystemA directly, for example, and then call A1.

Static façades

In most cases, there will only be one instance of a façade in the client for a set of subsystems, so its operations could more appropriately be called on the user's side as members of the class itself, as in:

public void ClientMain (  ) {
  Facade.Operation1(  );
  Facade.Operation2(  );
}

This implies that Facade is a static class. No instantiation is necessary; the user interfaces with the Facade class directly. In fact, the Singleton pattern (Chapter 5) would be the preferred way of achieving this effect.

Example: Novice Photo Library

Consider the Composite pattern example in Chapter 3 that showed how photos could be loaded into directories of arbitrary configurations. The instructions for using the six commands relied on the current place ("where I am"), which was a powerful, but perhaps confusing, concept. For novices, it might be a good idea to abstract from the power of the Photo Library and just let them load sets of photos, all at the same level, and immediately display them (as Flickr does). The commands could simply be:

Upload setname
photoname1 photoname2 ...

ending with a blank line or some other indicator. These instructions would translate into the following existing ones:

Find album
AddSet setname
AddPhoto photoname1
AddPhoto photoname2
...
Display

Instead of going in and altering the code to have a new command, we can have a completely separate Façade that makes the calls as described above. The more complex and rich commands might be available to expert users, but not to novices. (See the preceding discussion on opaque and transparent façades.)

Use

Façades can be useful in different circumstances. There are many instances where a computer system is built up out of a set of largely independent subsystems. One well-known case is a compiler: it consists of clearly identifiable subsystems called a lexical analyzer, a syntax analyzer, semantic analyzers, a code generator, and several optimizers. In modern compilers, each subsystem has many subtasks. The different tasks and subtasks are called in a sequence, but sometimes they are not all needed. For example, if an error occurs in one of the analysis tasks, the compiler might not go onto a later phase. (The .NET compilers follow this approach.) Hiding this detail behind a façade enables a program to call tasks within subsystems in a logical order, passing the necessary data structures between them.

Use the Façade pattern when...

A system has several identifiable subsystems and:

  • The abstractions and implementations of a subsystem are tightly coupled.

  • The system evolves and gets more complex, but early adopters might want to retain their simple views.

  • You want to provide alternative novice, intermediate, and "power user" interfaces.

  • There is a need for an entry point to each level of layered software.

But consider using instead:

  • The Abstract Factory pattern for designs where subsystems create objects on behalf of the client.

Choose the Façade you need...

Opaque

Subsystem operations can only be called through the Façade.

Transparent

Subsystem operations can be called directly as well as through the Façade.

Singleton

Only one instance of the Façade is meaningful.

Exercises

  1. Program the suggested extension for novices to the Photo Library program.

  2. Consider large systems that you use on the Internet, and come up with more examples of Façades.

  3. If you have access to source code for a compiler, find the part where the subsystems are called and examine how the data structures are passed between them.

Get C# 3.0 Design Patterns now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.