Facade Design Pattern


Definition

GOF --> Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.

Note:
  1. Wrap a complicated subsystem with a simpler interface.
  2. The biggest assumption in Facade pattern is that objects are often Singletons because only one Facade object is required.
  3. Facade defines a new interface
  4. Both, Adapter and Facade are both wrappers. But they are different kinds of wrappers. The intent of Facade is to produce a simpler interface but new, and the intent of Adapter is to design to an existing interface may be one or more. Facade characteristically wraps multiple objects and Adapter wraps a single object.
  5. Abstract Factory can be used as an option to Facade to hide platform-specific classes.
Best examples are
  1. Front desk for any company.
  2. Customer care Help desk.
  3. Amazon.com 1-Click system
Design

See the basic and Singleton facade examples

UML Diagram

From GoF
 
1.gif 

2.gif

Code

Basic Example

public class SubSystemOne
{
    public void MethodOne()
    {
        Console.WriteLine(" Sub System One Method is called");
    }
}
public class SubSystemTwo
{
    public void MethodTwo()
    {
        Console.WriteLine(" Sub System Two Method is called");
    }
}
public class SubSystemThree
{
    public void MethodThree()
    {
        Console.WriteLine(" Sub System Three Method is called");
    }
}
// "Facade"
public class Façade
{
    FacadeSample.SubSystemOne _subSystemOne;
    FacadeSample.SubSystemTwo _subSystemTwo;
    FacadeSample.SubSystemThree _subSystemThree;
    Facade()
    {
        _subSystemOne = new FacadeSample.SubSystemOne();
        _subSystemTwo = new FacadeSample.SubSystemTwo();
        _subSystemThree = new FacadeSample.SubSystemThree();
    }
    public void MethodA()
    {
        Console.WriteLine("\n Facade MethodA() is calling ---- ");
        _subSystemOne.MethodOne();
        _subSystemTwo.MethodTwo();
    }
    public void MethodB()
    {
        Console.WriteLine("\n Facade MethodB() is calling---- ");
        _subSystemTwo.MethodTwo();
        _subSystemThree.MethodThree();
    }
    public void MethodC()
    {
        Console.WriteLine("\n Facade MethodC() is calling---- ");
        _subSystemOne.MethodOne();
        _subSystemThree.MethodThree();
    }
}

Facade facade = new Facade();
facade.MethodA();
facade.MethodB();

In the classic example above, all the sub-systems are exposed to the outside world. So we need to restict the access to the sub-systems from the outside world.

Make all sub-system access modifiers internal.

Also, as said, Facade object should be one instance in the application. So just by changing to static class we can achieve this but what if two threads are trying to create? Again it will allow a single instance per thread.

So make sure it should be perfect singleton.

namespace FacadeSample
{
    internal class SubSystemOne
    {
        internal void MethodOne()
        {
            Console.WriteLine(" Sub System One Method is called");
        }
    }
    internal class SubSystemTwo
    {
        internal void MethodTwo()
        {
            Console.WriteLine(" Sub System Two Method is called");
        }
    }
    internal class SubSystemThree
    {
        internal void MethodThree()
        {
            Console.WriteLine(" Sub System Three Method is called");
        }
    }
}

// "Facade"
public class Facade
{
    FacadeSample.SubSystemOne _subSystemOne;
    FacadeSample.SubSystemTwo _subSystemTwo;
    FacadeSample.SubSystemThree _subSystemThree;
    Facade()
    {
        _subSystemOne = new FacadeSample.SubSystemOne();
        _subSystemTwotwo = new FacadeSample.SubSystemTwo();
        _subSystemThree = new FacadeSample.SubSystemThree();
    }
    static Facade()
    {
    }
    static readonly Facade facadeInstance = new Facade();
    public static Facade FacadeInstance
    {
        get { return facadeInstance; }
    }
    public void MethodA()
    {
        Console.WriteLine("\n Facade MethodA() is calling ---- ");
        _subSystemOne.MethodOne();
        _subSystemTwo.MethodTwo();
    }
    public void MethodB()
    {
        Console.WriteLine("\n Facade MethodB() is calling---- ");
        _subSystemTwo.MethodTwo();
        _subSystemThree.MethodThree();
    }
    public void MethodC()
    {
        Console.WriteLine("\n Facade MethodC() is calling---- ");
        _subSystemOne.MethodOne();
        _subSystemThreethree.MethodThree();
    }
}

Client

Facade facade = Facade.FacadeInstance;
facade.MethodA();
facade.MethodB();