Facade Design Pattern


Intent

It is belongs to structural design patterns catalog.
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.

Explanation

Real world example

How does a goldmine work? "Well, the miners go down there and dig gold!" you say. That is what you believe because you are using a simple interface that goldmine provides on the outside, internally it has to do a lot of stuff to make it happen. This simple interface to the complex subsystem is a facade.

In plain words

Facade pattern provides a simplified interface to a complex subsystem.

Wikipedia says

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

Structure

Class Diagram


Source code (First Example)



Let's build a Home Theater using Facade Pattern.
Here Facade class treats the home theater components as a subsystem, and calls the subsystem to implement it's watch movie method.
Step 1 : Create Amplifier java class.
public class Amplifier {
String description;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;

public Amplifier(String description) {
this.description = description;
}

public void on() {
System.out.println(description + " on");
}

public void off() {
System.out.println(description + " off");
}

public void setStereoSound() {
System.out.println(description + " stereo mode on");
}

public void setSurroundSound() {
System.out.println(description + " surround sound on (5 speakers, 1 subwoofer)");
}

public void setVolume(int level) {
System.out.println(description + " setting volume to " + level);
}

public void setTuner(Tuner tuner) {
System.out.println(description + " setting tuner to " + dvd);
this.tuner = tuner;
}

public void setDvd(DvdPlayer dvd) {
System.out.println(description + " setting DVD player to " + dvd);
this.dvd = dvd;
}

public void setCd(CdPlayer cd) {
System.out.println(description + " setting CD player to " + cd);
this.cd = cd;
}

public String toString() {
return description;
}
}
Step 2 :  Create CdPlayer java class.
public class CdPlayer {
String description;
int currentTrack;
Amplifier amplifier;
String title;

public CdPlayer(String description, Amplifier amplifier) {
this.description = description;
this.amplifier = amplifier;
}

public void on() {
System.out.println(description + " on");
}

public void off() {
System.out.println(description + " off");
}

public void eject() {
title = null;
System.out.println(description + " eject");
}

public void play(String title) {
this.title = title;
currentTrack = 0;
System.out.println(description + " playing \"" + title + "\"");
}

public void play(int track) {
if (title == null) {
System.out.println(description + " can't play track " + currentTrack +
", no cd inserted");
} else {
currentTrack = track;
System.out.println(description + " playing track " + currentTrack);
}
}

public void stop() {
currentTrack = 0;
System.out.println(description + " stopped");
}

public void pause() {
System.out.println(description + " paused \"" + title + "\"");
}

public String toString() {
return description;
}
}
Step 3 : Create DvdPlayer java class.
public class DvdPlayer {
String description;
int currentTrack;
Amplifier amplifier;
String movie;

public DvdPlayer(String description, Amplifier amplifier) {
this.description = description;
this.amplifier = amplifier;
}

public void on() {
System.out.println(description + " on");
}

public void off() {
System.out.println(description + " off");
}

public void eject() {
movie = null;
System.out.println(description + " eject");
}

public void play(String movie) {
this.movie = movie;
currentTrack = 0;
System.out.println(description + " playing \"" + movie + "\"");
}

public void play(int track) {
if (movie == null) {
System.out.println(description + " can't play track " + track + " no dvd inserted");
} else {
currentTrack = track;
System.out.println(description + " playing track " + currentTrack + " of \"" + movie + "\"");
}
}

public void stop() {
currentTrack = 0;
System.out.println(description + " stopped \"" + movie + "\"");
}

public void pause() {
System.out.println(description + " paused \"" + movie + "\"");
}

public void setTwoChannelAudio() {
System.out.println(description + " set two channel audio");
}

public void setSurroundAudio() {
System.out.println(description + " set surround audio");
}

public String toString() {
return description;
}
}
Step 4 : Create Projector java class.
public class Projector {
String description;
DvdPlayer dvdPlayer;

public Projector(String description, DvdPlayer dvdPlayer) {
this.description = description;
this.dvdPlayer = dvdPlayer;
}

public void on() {
System.out.println(description + " on");
}

public void off() {
System.out.println(description + " off");
}

public void wideScreenMode() {
System.out.println(description + " in widescreen mode (16x9 aspect ratio)");
}

public void tvMode() {
System.out.println(description + " in tv mode (4x3 aspect ratio)");
}

public String toString() {
return description;
}
}
Step 5 : Create TheaterLights java class.
public class TheaterLights {
String description;

public TheaterLights(String description) {
this.description = description;
}

public void on() {
System.out.println(description + " on");
}

public void off() {
System.out.println(description + " off");
}

public void dim(int level) {
System.out.println(description + " dimming to " + level + "%");
}

public String toString() {
return description;
}
}
Step 6 : Create Screen java class.
public class Screen {
String description;

public Screen(String description) {
this.description = description;
}

public void up() {
System.out.println(description + " going up");
}

public void down() {
System.out.println(description + " going down");
}


public String toString() {
return description;
}
}
Step 7 : Create PopcornPopper java class.
public class PopcornPopper {
String description;

public PopcornPopper(String description) {
this.description = description;
}

public void on() {
System.out.println(description + " on");
}

public void off() {
System.out.println(description + " off");
}

public void pop() {
System.out.println(description + " popping popcorn!");
}


public String toString() {
return description;
}
}
Step 8 :  Let's create Facade Java class - HomeTheaterFacade.
public class HomeTheaterFacade {
Amplifier amp;
Tuner tuner;
DvdPlayer dvd;
CdPlayer cd;
Projector projector;
TheaterLights lights;
Screen screen;
PopcornPopper popper;

public HomeTheaterFacade(Amplifier amp,
Tuner tuner,
DvdPlayer dvd,
CdPlayer cd,
Projector projector,
Screen screen,
TheaterLights lights,
PopcornPopper popper)
{

this.amp = amp;
this.tuner = tuner;
this.dvd = dvd;
this.cd = cd;
this.projector = projector;
this.screen = screen;
this.lights = lights;
this.popper = popper;
}

public void watchMovie(String movie) {
System.out.println("Get ready to watch a movie...");
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() {
System.out.println("Shutting movie theater down...");
popper.off();
lights.on();
screen.up();
projector.off();
amp.off();
dvd.stop();
dvd.eject();
dvd.off();
}

public void listenToCd(String cdTitle) {
System.out.println("Get ready for an audiopile experence...");
lights.on();
amp.on();
amp.setVolume(5);
amp.setCd(cd);
amp.setStereoSound();
cd.on();
cd.play(cdTitle);
}

public void endCd() {
System.out.println("Shutting down CD...");
amp.off();
amp.setCd(cd);
cd.eject();
cd.off();
}

public void listenToRadio(double frequency) {
System.out.println("Tuning in the airwaves...");
tuner.on();
tuner.setFrequency(frequency);
amp.on();
amp.setVolume(5);
amp.setTuner(tuner);
}

public void endRadio() {
System.out.println("Shutting down the tuner...");
tuner.off();
amp.off();
}
}
Step 9 :  Now we test the Facade design pattern.
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("Raiders of the Lost Ark");
homeTheater.endMovie();
}
}
Output : 
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 "Raiders of the Lost Ark"
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 "Raiders of the Lost Ark"
Top-O-Line DVD Player eject
Top-O-Line DVD Player off

Source code (Second Example)

Step 1 : Create a MobileShop interface.
public interface MobileShop {  
public void modelNo();
public void price();
}
Step 2 : Create a Iphone implementation class that will  implement Mobileshop interface.
public class Iphone implements MobileShop {  
@Override
public void modelNo() {
System.out.println(" Iphone 6 ");
}
@Override
public void price() {
System.out.println(" Rs 65000.00 ");
}
}
Step 3 : Create a Samsung implementation class that will implement Mobileshop interface.
public class Samsung implements MobileShop {  
@Override
public void modelNo() {
System.out.println(" Samsung galaxy tab 3 ");
}
@Override
public void price() {
System.out.println(" Rs 45000.00 ");
}
}
Step 4 : Create a Blackberry implementation class that will implement Mobileshop interface .
public class Blackberry implements MobileShop {  
@Override
public void modelNo() {
System.out.println(" Blackberry Z10 ");
}
@Override
public void price() {
System.out.println(" Rs 55000.00 ");
}
}
Step 5 : Create a ShopKeeper concrete class that will use MobileShop interface.
public class ShopKeeper {  
private MobileShop iphone;
private MobileShop samsung;
private MobileShop blackberry;

public ShopKeeper(){
iphone= new Iphone();
samsung=new Samsung();
blackberry=new Blackberry();
}
public void iphoneSale(){
iphone.modelNo();
iphone.price();
}
public void samsungSale(){
samsung.modelNo();
samsung.price();
}
public void blackberrySale(){
blackberry.modelNo();
blackberry.price();
}
}
Step 6 : Now, Creating a client that can purchase the mobiles from MobileShop through ShopKeeper.
import java.io.BufferedReader;  
import java.io.IOException;
import java.io.InputStreamReader;

public class FacadePatternClient {
private static int choice;
public static void main(String args[]) throws NumberFormatException, IOException{
do{
System.out.print("========= Mobile Shop ============ \n");
System.out.print(" 1. IPHONE. \n");
System.out.print(" 2. SAMSUNG. \n");
System.out.print(" 3. BLACKBERRY. \n");
System.out.print(" 4. Exit. \n");
System.out.print("Enter your choice: ");

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
choice=Integer.parseInt(br.readLine());
ShopKeeper sk=new ShopKeeper();

switch (choice) {
case 1:
{
sk.iphoneSale();
}
break;
case 2:
{
sk.samsungSale();
}
break;
case 3:
{
sk.blackberrySale();
}
break;
default:
{
System.out.println("Nothing You purchased");
}
return;
}

}while(choice!=4);
}
}
Output :
========= Mobile Shop ============  
1. IPHONE.
2. SAMSUNG.
3. BLACKBERRY.
4. Exit.
Enter your choice: 1
Iphone 6
Rs 65000.00
========= Mobile Shop ============
1. IPHONE.
2. SAMSUNG.
3. BLACKBERRY.
4. Exit.
Enter your choice: 2
Samsung galaxy tab 3
Rs 45000.00
========= Mobile Shop ============
1. IPHONE.
2. SAMSUNG.
3. BLACKBERRY.
4. Exit.
Enter your choice: 3
Blackberry Z10
Rs 55000.00
========= Mobile Shop ============
1. IPHONE.
2. SAMSUNG.
3. BLACKBERRY.
4. Exit.
Enter your choice: 4
Nothing You purchased

Applicability

Use the Facade pattern when
  • you want to provide a simple interface to a complex subsystem. Subsystems often get more complex as they evolve. Most patterns, when applied, result in more and smaller classes. This makes the subsystem more reusable and easier to customize, but it also becomes harder to use for clients that don't need to customize it. A facade can provide a simple default view of the subsystem that is good enough for most clients. Only clients needing more customizability will need to look beyond the facade.
  • there are many dependencies between clients and the implementation classes of an abstraction. Introduce a facade to decouple the subsystem from clients and other subsystems, thereby promoting subsystem independence and portability.
  • you want to layer your subsystems. Use a facade to define an entry point to each subsystem level. If subsystems are dependent, then you can simplify the dependencies between them by making them communicate with each other solely through their facades.

Credits


Comments

Popular posts from this blog

Design Patterns used in Hibernate Framework

Value List Handler