Facade Pattern

The pattern allows:

  • a single interface to a set of interfaces within a system;
  • a software library easier to use, understand and test, since the facade has convenient methods for common tasks;
  • to make code that uses the library more readable, for the same reason;
  • to wrap a poorly-designed collection of APIs with a single well-designed API.

As I have told already the Adapter pattern is used when different interfaces must be accessible as a declared particular one. It is assumed to support a polymorphic behavior. The Façade pattern is used when an easier and simpler interface to work with is required.


Facade Pattern


PHP Example

<?php
/*
 * @category Design Pattern Tutorial
 * @package Façade Sample
 * @author Dmitry Sheiko <me@dsheiko.com>
 * @link http://dsheiko.com
 */

class Lib_String
{
    public static function parseHomographs($text)
    {
       static $homographs = null;
       if ($homographs === null) {
           // include "../homographs.php"
           $homographs = array(); // TILT
       }
       $text = strtr($text, $homographs);
    }
    public static function removeControlChars($text)
    {
        $text = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $text);
    }
    public static function removeMultipleSpaces($text)
    {
        $text = preg_replace('# {2,}#', ' ', $text);
    }
}

class Model_UserFacade
{
    public function getCleanUsername($username)
    {
        $username = Lib_String::parseHomographs($username);
        $username = Lib_String::removeControlChars($username);
        $username = Lib_String::removeMultipleSpaces($username);
        return trim($username);
    }
}

JS/ES5 Example

Addy Osmani used the Façade pattern in his remarkable article Patterns For Large-Scale JavaScript Application Architecture. Here is a simplified extract, showing the usage of Façade.

/*
 * @category Design Pattern Tutorial
 * @package Façade Sample
 * @author Dmitry Sheiko <me@dsheiko.com>
 * @link http://dsheiko.com
 */
(function() {

var NotificationWidget = (function() {
    var _private = {
        data: [],
        populate : function( data ) {
            this.data = data;
        },
        show : function() {
            console.log('Widget displayed with the data:');
            this.data.forEach(function(val){
                console.log(val);
            });
        }
    };
    return {
        facade : function( args ) {
            _private.populate(args.data);
            if ( args.show ) {
                _private.show();
            }
        }
    }
}());

/**
 * Usage
 */

NotificationWidget.facade({show: true, data: ['One gets message', 'Another gets like']});

// Output:
// Widget displayed with the data:
// One gets message
// Another gets like

}());