Search code examples
implementationfacade

Facade Design Pattern - Implementation


I am referring the book Elements of Reusable Object Oriented Software by Eric Gamma on degign patterns. I however understood the concept of Facade pattern, but still not able to understand the implementation points which has been given in the book as I am little poor with the implementing part esp.

The below are the 2 points mentioned in the book:

  1. Reduce client subsystem coupling: by making the Facade class an abstract class.

  2. Public v/s Private subsystem classes.

Could someone please explain me this with some example or with the code I have:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Facade_CSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            Facade facade = new Facade();

            facade.ProcessA();
            facade.ProcessB();

            // Wait for user
            Console.ReadKey();
        }
    }

     /// <summary>
  /// The 'Subsystem ClassA' class
  /// </summary>
  class SubSystemOne
  {
    public void MethodOne()
    {
      Console.WriteLine(" SubSystem One");
    }
  }

  /// <summary>
  /// The 'Subsystem ClassB' class
  /// </summary>
  class SubSystemTwo
  {
    public void MethodTwo()
    {
      Console.WriteLine(" SubSystem Two");
    }
  }

  /// <summary>
  /// The 'Subsystem ClassC' class
  /// </summary>
  class SubSystemThree
  {
    public void MethodThree()
    {
      Console.WriteLine(" SubSystem Three");
    }
  }

  /// <summary>
  /// The 'Subsystem ClassD' class
  /// </summary>
  class SubSystemFour
  {
    public void MethodFour()
    {
      Console.WriteLine(" SubSystem Four");
    }
  }

  /// <summary>
  /// The 'Facade' class
  /// </summary>
  class Facade
  {
    private SubSystemOne _one;
    private SubSystemTwo _two;
    private SubSystemThree _three;
    private SubSystemFour _four;

    public Facade()
    {
        Console.WriteLine("\nRequests received from Client System and Facade is in execution... ");

      _one = new SubSystemOne();
      _two = new SubSystemTwo();
      _three = new SubSystemThree();
      _four = new SubSystemFour();
    }

    public void ProcessA()
    {
      Console.WriteLine("\nProcessA of Facade uses the following subsystems to accomplish the task:");
      _one.MethodOne();
      _two.MethodTwo();
      _four.MethodFour();
    }

    public void ProcessB()
    {
        Console.WriteLine("\nProcessB of Facade uses the following subsystems to accomplish the task:");
      _two.MethodTwo();
      _three.MethodThree();
    }
  }
}

Code with Abstract Class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Facade_abstract
{
    class Program
    {
        static void Main(string[] args)
        {
            FacadeAbs facade = new FacadeAbs();

            facade.ProcessA();
            facade.ProcessB();

            // Wait for user
            Console.ReadKey();

        }
    }

    class SubSystemOne
    {
        public void MethodOne()
        {
            Console.WriteLine(" SubSystem One");
        }
    }

    /// <summary>
    /// The 'Subsystem ClassB' class
    /// </summary>
    class SubSystemTwo
    {
        public void MethodTwo()
        {
            Console.WriteLine(" SubSystem Two");
        }
    }

    /// <summary>
    /// The 'Subsystem ClassC' class
    /// </summary>
    class SubSystemThree
    {
        public void MethodThree()
        {
            Console.WriteLine(" SubSystem Three");
        }
    }

    /// <summary>
    /// The 'Subsystem ClassD' class
    /// </summary>
    class SubSystemFour
    {
        public void MethodFour()
        {
            Console.WriteLine(" SubSystem Four");
        }
    }

    /// <summary>
    /// The 'Facade' class
    /// </summary>
    public abstract class Facade
    {
        //public abstract Facade();

        public abstract void ProcessA();

        public abstract void ProcessB();

    }

    public class FacadeAbs : Facade
    {
        private SubSystemOne _one;
        private SubSystemTwo _two;
        private SubSystemThree _three;
        private SubSystemFour _four;

        public FacadeAbs()
        {
            Console.WriteLine("\nRequests received from Client System and Facade is in execution... ");

            _one = new SubSystemOne();
            _two = new SubSystemTwo();
            _three = new SubSystemThree();
            _four = new SubSystemFour();
        }


        public override void ProcessA()
        {
            Console.WriteLine("\nProcessA of Facade uses the following subsystems to accomplish the task:");
            _one.MethodOne();
            _two.MethodTwo();
            _four.MethodFour();
        }

        public override void ProcessB()
        {
            Console.WriteLine("\nProcessB of Facade uses the following subsystems to accomplish the task:");
            _two.MethodTwo();
            _three.MethodThree();
        }

    }
}

Solution

  • Facade is used to reduce the coupling between the programs.

    As in the example ProcessA calls 3 methods -
    _one.MethodOne();
    _two.MethodTwo();
    _four.MethodFour();

    And the client just calls the ProcessA method. The facade is used just to reduce the coupling, dependency.

    If no facade the client will be the one to call these methods.

    So the Facade class provides the following -

    1. Hides the multiple calls. This helps as the client will have to make just a single call. prevents tight coupling. e.g. ProcessA only
    2. If any of the method changes add or removes the arguments, the client code needs to change. However in case of facade the change does not impact the client.
    3. The client has just a few public access points to the server side. And the server side can encapsulate its code. Less points of failure.