Façade Pattern

Definition

Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.

Explanation

The facade pattern (or façade pattern) is a software design pattern commonly used with object-oriented programming. The name is by analogy to an architectural facade.

A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:

  • make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;
  • make the library more readable, for the same reason;
  • reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;
  • wrap a poorly designed collection of APIs with a single well-designed API (as per task needs).

The Facade design pattern is often used when a system is very complex or difficult to understand because the system has a large number of interdependent classes or its source code is unavailable. This pattern hides the complexities of the larger system and provides a simpler interface to the client. It typically involves a single wrapper class which contains a set of members required by client. These members access the system on behalf of the facade client and hide the implementation details.

A Facade is used when an easier or simpler interface to an underlying object is desired. Alternatively, an adapter can be used when the wrapper must respect a particular interface and must support polymorphic behavior. A decorator makes it possible to add or alter behavior of an interface at run-time.

Adapter
Converts one interface to another so that it matches what the client is expecting
Decorator
Dynamically adds responsibility to the interface by wrapping the original code
Facade
Provides a simplified interface

Screencast

TypeScript Code

module Facade {
    class Customer {
        constructor(public name: string) {
        }
    }

    class Bank {
        public static hasSufficientSavings(customer: Customer, amount: number): boolean {
            Output.WriteLine("Check bank for " + customer.name);
            return true;
        }
    }

    class Credit {
        public static hasGoodCredit(customer: Customer): boolean {
            Output.WriteLine("Check credit for " + customer.name);
            return true;
        }
    }

    class Loan {
        public static hasNoBadLoans(customer: Customer): boolean {
            Output.WriteLine("Check loans for " + customer.name);
            return true;
        }
    }

    class Mortgage {
        public static IsEligible(customer: Customer, amount: number): boolean {
            Output.WriteLine(customer.name + " applies for a loan of " + amount + " dollar.");

            var eligible: boolean = true;

            if (!Bank.hasSufficientSavings(customer, amount)) {
                eligible = false;
            }
            else if (!Loan.hasNoBadLoans(customer)) {
                eligible = false;
            }
            else if (!Credit.hasGoodCredit(customer)) {
                eligible = false;
            }

            return eligible;
        }
    }

    window.addEventListener("load", function () {
        var customer = new Customer("Wesley Bakker");
        var elegible: boolean = Mortgage.IsEligible(customer, 1000000);
        Output.WriteLine(customer.name + " has been " + (elegible ? "approved" : "rejected"));
    });
}

Output