Sunday, June 19, 2011

Facade Pattern



Facade Pattern provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher level interface that makes the subsystem easy to use.
Motivation
Structuring a system into subsystems helps reduce complexity of groups of classes and other subsystems
The interface exposed by the classes in a subsystem or set of subsystems can become quite complex
One way to reduce this complexity is to introduce a facade object that provides a single, simplified interface to the more general facilities of a subsystem. 
Applicability
Use the Facade pattern:

To provide a simple interface for a complex subsystem. The interface will be good enough for most of the clients.

It decouples the classes of the subsystem from its clients and other subsystems, thereby promoting independence and portability.

Facade Pattern at First Glance:
Let us understand this with the help of the diagram which makes it easier to understand and remember it.
Customer Care Representative


Here we are given only one contact number of Customer care representatives who will do all the work for us and delegate our call to the concerned department.

This really makes our job simpler. We are just interacting with and single person to get all our jobs done. She will take all the pain to get the relevant information for us.

Below is another diagram which helps us to understand the structure and working of Façade Design Pattern.
Complex System and a Facade Class


Let us take an example from the most popular book Head First Java to understand the dynamics behind it.

Think we want to watch a movie to rejuvenate our mind but before we do that we need to finish a few small tasks let us list them.


Oh god now this looks like watching a movie is a Big Rocket Science. Let us have a look at all these components put together.

Class structure of Movie theater System

This appears very complex and hard. Ahh... I will never watch a movie after taking so much of pain.

This is not enough there is something more waiting for us. We have to turn everything off once we finish the movie. Who cares for it once the movie is over….Here we have no choice else we need to pay high electricity bills.
Now let us see how façade can get us out of this mess so that we can watch the movie.
Façade is just what we need. By using façade pattern we can take a complex system and make is easier to use by implementing a Façade Class.
Class structure of Movie theater System simplified by a Facade
We can also have number of Facades in a system if the system is very complex or involves many complex subsystems.
Let us try out Some Coding
We have HomeTheaterFacade which has a composition of all the components so that it can have access to all these components.
public class HomeTheaterFacade {
      Amplifier amp;
      Tuner tuner;
      DvdPlayer dvd;
      CdPlayer cd;
      Projector projector;
      TheaterLights lights;
      Screen screen;
      PopcornPopper popper;

      public HomeTheaterFacade() {
            // This will be a parameterised constructor
      }

      public void watchMovie(String movie) {
            // This method takes to start all the devices
            popper.on();
            popper.pop();
            lights.dim(10);
            screen.down();
            projector.on();
            projector.wideScreenMode();
            amp.on();
            amp.setDvd(dvd);
            amp.setSurroundSound();
            amp.setVolume(5);
            dvd.on();
            dvd.play(movie);
      }

      public void endMovie() {
            // This method takes to shut down all the devices
            popper.off();
            lights.on();
            screen.up();
            projector.off();
            amp.off();
            dvd.stop();
            dvd.eject();
            dvd.off();
      }
     // These methods can also be implemented to perform the task
      public void listenToCd(String cdTitle) {       
      }

      public void endCd() {        
      }

      public void listenToRadio(double frequency) {        
      }

      public void endRadio() {           
      }
}







    It’s show time now let’s watch the movie
Hangover

  public class HomeTheaterTestDrive {
      public static void main(String[] args) {
            Amplifier amp = new Amplifier("Top-O-Line Amplifier");
            Tuner tuner = new Tuner("Top-O-Line AM/FM Tuner", amp);
            DvdPlayer dvd = new DvdPlayer("Top-O-Line DVD Player", amp);
            CdPlayer cd = new CdPlayer("Top-O-Line CD Player", amp);
            Projector projector = new Projector("Top-O-Line Projector", dvd);
            TheaterLights lights = new TheaterLights("Theater Ceiling Lights");
            Screen screen = new Screen("Theater Screen");
            PopcornPopper popper = new PopcornPopper("Popcorn Popper");

            HomeTheaterFacade homeTheater =
                        new HomeTheaterFacade(amp, tuner, dvd, cd,
                                    projector, screen, lights, popper);

            homeTheater.watchMovie("Hangover");
            homeTheater.endMovie();
      }
}


Output is as below:

Get ready to watch a movie...
Popcorn Popper on
Popcorn Popper popping popcorn!
Theater Ceiling Lights dimming to 10%
Theater Screen going down
Top-O-Line Projector on
Top-O-Line Projector in widescreen mode (16x9 aspect ratio)
Top-O-Line Amplifier on
Top-O-Line Amplifier setting DVD player to Top-O-Line DVD Player
Top-O-Line Amplifier surround sound on (5 speakers, 1 subwoofer)
Top-O-Line Amplifier setting volume to 5
Top-O-Line DVD Player on
Top-O-Line DVD Player playing "Hangover"

Shutting movie theater down...

Popcorn Popper off
Theater Ceiling Lights on
Theater Screen going up
Top-O-Line Projector off
Top-O-Line Amplifier off
Top-O-Line DVD Player stopped "Hangover"
Top-O-Line DVD Player eject
Top-O-Line DVD Player off


You can take the complete source code from the below URL.
Benefits

  •        It hides the implementation of the subsystem from clients, making the subsystem easier to use
  •           It promotes weak coupling between the subsystem and its clients
  •        It reduces compilation dependencies in large software systems
  •    It simplifies porting systems to other platforms, because it's less likely that building one subsystem requires building all others

Note that Facade does not add any functionality, it just simplifies interface