[Back to Main Page]

Facade
Structural

Intent

Provides a unified interface to a set of inter-related services. Simplifies use and inclusion of the subservices.

Also Known As

Configuration

Example TinyOS Components

GenericComm, Matchbox

Motivation

Complex system components, such as a filesystem or networking abstraction, can be implemented across many components. Higher-level operations may be based on lower-level ones, and a user needs access to both. The composition can also not be vertical in nature: high-level functionality can be spread across several components for implementation reasons. Although implemented separately, these pieces of functionality are part of a cohesive whole that needs to be presented as a logical unit.

For example, the Matchbox filing system provides interfaces for reading, writing, and deleting files, as well as interfaces for metadata operations such as renaming. Each of these interfaces is implemented in a separate module. For example, the implemention of file writing depends on being able to read the file, in case it needs to be relocated: the Write component uses the Read component in its implementation, and Matchbox exports both.

Exporting the various interfaces in different components can make using the abstraction more difficult for the programmer. Instead of including a single component, a configuration would need to include several. Additionally, each part needs a separate configuration, increasing clutter in the component namespace.

The Facade pattern allows you to provide a uniform access point to interfaces provided by many components. A Facade is just a nesC configuration that exports the interfaces of several underlying components. Additionally, the Facade can wire the underlying components to satisfy dependencies.

Applicability

Use the Facade pattern when:

  • An abstraction is implemented as several separate components.
  • It is preferrable to present the abstraction in entirety rather than in parts.

Structure

Participants

  • Proxy: the component that all other components wire to. It encapsulates the implementation and exports its interfaces with pass-through wiring. It has the same signature as the Implementation component.
  • Implementation: the specific version of the component.
  • Users: components that want to use the functionality the abstraction provides.
  • Service: components providing functionality that the that abstraction depends on.

Collaborations

Consequences

Because the Facade names all of its sub-parts, they will all be included in the nesC component graph. nesC's code pruning can remove components that are not used, but if any component handles interrupts, then code in the interrupt paths will be included, as will any tasks that those interrupts post. If you expect applications to only use a very narrow part of an abstraction, then presenting it using a Facade can be wasteful.

Implementation

Sample Code

The Matchbox filing system is a good example of a Facade. Various file operations are all implemented in different components, but the top-level Matchbox configuration provides them as a unified abstraction:

configuration Matchbox {
  provides {
    interface StdControl;
    interface FileDelete;
    interface FileDir;
    interface FileRead[uint8_t fd];
    interface FileRename;
    interface FileWrite[uint8_t fd];
  }
  uses {
    interface Debug;

    /**
     * Signaled when the filing system is ready to accept operations.
     * @return Ignored.
     */
    event result_t ready();
  }
}
implementation {
  components Read, Write, Dir, Rename, Delete;

  ....

  FileDelete = Delete;
  FileDir = Dir;
  FileRead = Read;
  FileRename = Rename;
  FileWrite = Write;

  ...
}

Known Uses

Related Patterns

The Proxy pattern is similar to the Facade in that it exports interfaces, but it does so for a single component in order to simplify implementation selection and namespace management. In contrast, the Facade groups several pieces of functionality into a logical whole. However, as a Facade can also act in part as a Proxy, as the choice of actual implementations of the services is constrained to the Facade.

[Back to Main Page]

Last modified: Fri Jul 30 17:09:59 PDT 2004