© Vaskaran Sarcar 2019
Vaskaran SarcarJava Design Patternshttps://doi.org/10.1007/978-1-4842-4078-6_9

9. Facade Pattern

Vaskaran Sarcar1 
(1)
Bangalore, Karnataka, India
 

This chapter covers the facade pattern.

GoF Definition

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.

Concept

Facades make a client’s life easier. Suppose that there is a complex system where multiple objects need to perform a series of tasks, and you need to interact with the system. In a situation like this, facade can provide you a simplified interface that takes care of everything (the creation of those objects, providing the correct sequence of tasks, etc.). As a result, instead of interacting with multiple objects in a complicated way, you just interact with a single object.

It is one of those patterns that supports loose coupling. Here you emphasize the abstraction and hide the complex details by exposing a simple interface. As a result, the code becomes clearer and more attractive.

Real-World Example

Suppose that you are going to organize a birthday party, and you plan to invite 500 people. Nowadays, you can go to any party organizer and let them know the key information—party type, the date and time, number of attendees, and so forth. The organizer does the rest for you. You do not need to think about how the hall will be decorated, whether attendees will get their food from a buffet table or be served by the caterer, and so forth. So, you do not need to buy items from the store or decorate the party hall yourself—you just pay the organizer and let them do the job properly.

Computer-World Example

Think about a situation where you use a method from a library (in the context of a programming language). You do not care how the method is implemented in the library. You just call the method to experiment the easy usage of it.

Note

You can use the concept of facade design pattern effectively to make your JDBC application attractive. You can consider the java.net.URL class as an example of a facade pattern implementation.Consider the shorthand openStream() or getContent() methods in this class. The openStream() method returns openConnection().getInputStream() and the getContent() method returns openConnection.getContent().The getInputStream() and getContent() methods are further defined in the URLConnection class.

Illustration

In the following implementation, you create some robots, and later, you destroy those objects. (The word “destroy” is not used in the context of garbage collection in this example). Here you can construct or destroy a particular kind of robot by invoking simple methods like constructMilanoRobot() and destroyMilanoRobot() of the RobotFacade class.

From a client’s point of view, he/she needs to interact only with the facade (see FacadePatternExample.java). RobotFacade is taking full responsibility in creating or destroying a particular kind of robot. This facade is talking to each of the subsystems (RobotHands, RobotBody, RobotColor) to fulfill the client’s request. The RobotBody class includes two simple static methods that provide instructions prior to the creation or destruction of a robot.

So, in this implementation, the clients do not need to worry about the creation of the separate classes and the calling sequence of the methods.

Class Diagram

Figure 9-1 shows the class diagram.
../images/395506_2_En_9_Chapter/395506_2_En_9_Fig1_HTML.jpg
Figure 9-1

Class diagram

Package Explorer View

Figure 9-2 shows the high-level structure of the program.
../images/395506_2_En_9_Chapter/395506_2_En_9_Fig2_HTML.jpg
Figure 9-2

Package Explorer view

Implementation

Here’s the implementation.
// RobotBody.java
package jdp2e.facade.demo;
public class RobotBody
{
    //Instruction manual -how to create a robot
    public static void createRobot()
    {
        System.out.println(" Refer the manual before creation of a robot.");
    }
    //Method to create hands of a robot
    public void createHands()
    {
        System.out.println(" Hands manufactured.");
    }
    //Method to create remaining parts (other than hands) of a robot
    public void createRemainingParts()
    {
        System.out.println(" Remaining parts (other than hands) are created.");
    }
    //Instruction manual -how to destroy a robot
    public static void destroyRobot()
    {
        System.out.println(" Refer the manual before destroying of a robot.");
    }
    //Method to destroy hands of a robot
    public void destroyHands()
    {
        System.out.println(" The robot's hands are destroyed.");
    }
    //Method to destroy remaining parts (other than hands) of a robot
    public void destroyRemainingParts()
    {
        System.out.println(" The robot's remaining parts are destroyed.");
    }
}
//RobotColor.java
package jdp2e.facade.demo;
public class RobotColor
{
    public void setDefaultColor()
    {
        System.out.println(" This is steel color robot.");
    }
    public void setGreenColor()
    {
        System.out.println(" This is a green color robot.");
    }
}
// RobotHands.java
package jdp2e.facade.demo;
public class RobotHands
{
    public void setMilanoHands()
    {
        System.out.println(" The robot will have EH1 Milano hands.");
    }
    public void setRobonautHands()
    {
        System.out.println(" The robot will have Robonaut hands.");
    }
    public void resetMilanoHands()
    {
        System.out.println(" EH1 Milano hands are about to be destroyed.");
    }
    public void resetRobonautHands()
    {
        System.out.println(" Robonaut hands are about to be destroyed.");
    }
}
// RobotFacade.java
package jdp2e.facade.demo;
public class RobotFacade
{
    RobotColor rColor;
    RobotHands rHands ;
    RobotBody rBody;
    public RobotFacade()
    {
        rColor = new RobotColor();
        rHands = new RobotHands();
        rBody = new RobotBody();
    }
    //Constructing a Milano Robot
    public void constructMilanoRobot()
    {
        RobotBody.createRobot();
        System.out.println("Creation of a Milano Robot Start.");
        rColor.setDefaultColor();
        rHands.setMilanoHands();
        rBody.createHands();
        rBody.createRemainingParts();
        System.out.println(" Milano Robot Creation End.");
        System.out.println();
    }
    //Constructing a Robonaut Robot
    public void constructRobonautRobot()
    {
        RobotBody.createRobot();
        System.out.println("Initiating the creational process of a Robonaut Robot.");
        rColor.setGreenColor();
        rHands.setRobonautHands();
        rBody.createHands();
        rBody.createRemainingParts();
        System.out.println("A Robonaut Robot is created.");
        System.out.println();
    }
    //Destroying a Milano Robot
    public void destroyMilanoRobot()
    {
        RobotBody.destroyRobot();
        System.out.println(" Milano Robot's destruction process is started.");
        rHands.resetMilanoHands();
        rBody.destroyHands();
        rBody.destroyRemainingParts();
        System.out.println(" Milano Robot's destruction process is over.");
        System.out.println();
    }
    //Destroying a Robonaut Robot
    public void destroyRobonautRobot()
    {
        RobotBody.destroyRobot();
        System.out.println(" Initiating a Robonaut Robot's destruction process.");
        rHands.resetRobonautHands();
        rBody.destroyHands();
        rBody.destroyRemainingParts();
        System.out.println(" A Robonaut Robot is destroyed.");
        System.out.println();
    }
}
//Client code
//FacadePatternExample.java
package jdp2e.facade.demo;
public class FacadePatternExample {
    public static void main(String[] args) {
        System.out.println("***Facade Pattern Demo*** ");
        //Creating Robots
        RobotFacade milanoRobotFacade = new RobotFacade();
        milanoRobotFacade.constructMilanoRobot();
        RobotFacade robonautRobotFacade = new RobotFacade();
        robonautRobotFacade.constructRobonautRobot();
        //Destroying robots
        milanoRobotFacade.destroyMilanoRobot();
        robonautRobotFacade.destroyRobonautRobot();
    }
}

Output

Here’s the output.
***Facade Pattern Demo***
 Refer the manual before creation of a robot.
Creation of a Milano Robot Start.
 This is steel color robot.
 The robot will have EH1 Milano hands.
 Hands manufactured.
 Remaining parts (other than hands) are created.
 Milano Robot Creation End.
 Refer the manual before creation of a robot.
Initiating the creational process of a Robonaut Robot.
 This is a green color robot.
 The robot will have Robonaut hands.
 Hands manufactured.
 Remaining parts (other than hands) are created.
A Robonaut Robot is created.
 Refer the manual before destroying of a robot.
 Milano Robot's destruction process is started.
 EH1 Milano hands are about to be destroyed.
 The robot's hands are destroyed.
 The robot's remaining parts are destroyed.
 Milano Robot's destruction process is over.
 Refer the manual before destroying of a robot.
 Initiating a Robonaut Robot's destruction process.
 Robonaut hands are about to be destroyed.
 The robot's hands are destroyed.
 The robot's remaining parts are destroyed.
 A Robonaut Robot is destroyed .

Q&A Session

  1. 1.
    What are key advantages of using a facade pattern?
    • If a system consists of many subsystems, managing all those subsystems becomes very tough and clients may find their life difficult to communicate separately with each of these subsystems. In this scenario, facade patterns are very much handy. It provides a simple interface to clients. In simple words, instead of presenting complex subsystems, you present one simplified interface to clients. This approach also promotes weak coupling by separating a client from the subsystems.

    • It can also help you to reduce the number of objects that a client needs to deal with.

     
  2. 2.

    I see that the facade class is using compositions. Is this intentional?

    Yes. With this approach, you can easily access the methods in each subsystem.

     
  3. 3.

    It appears to me that facades do not restrict us to directly connect with subsystems. Is this understanding correct?

    Yes. A facade does not encapsulate the subsystem classes or interfaces. It just provides a simple interface (or layer) to make your life easier. You are free to expose any functionality of the subsystem, but in those cases, your code may look dirty, and at the same time, you lose all the benefits associated with this pattern.

     
  4. 4.

    How is it different from adapter design pattern?

    In the adapter pattern, you try to alter an interface so that the clients do not feel the difference between the interfaces. The facade pattern simplifies the interface. They present the client a simple interface to interact with (instead of a complex subsystem).

     
  5. 5.

    There should be only one facade for a complex subsystem. Is this correct?

    Not at all. You can create any number of facades for a particular subsystem.

     
  6. 6.

    Can I add more stuffs/logic with a facade?

    Yes, you can.

     
  7. 7.
    What are the challenges associated with a facade pattern?
    • Subsystems are connected with the facade layer. So, you need to take care of an additional layer of coding (i.e., your codebase increases).

    • When the internal structure of a subsystem changes, you need to incorporate the changes in the facade layer also.

    • Developers need to learn about this new layer, whereas some of them may already be aware of how to use the subsystems/APIs efficiently.

     
  8. 8.

    How is it different from the mediator design pattern?

    In a mediator pattern implementation, subsystems are aware of the mediator. They talk to each other. But in a facade, subsystems are not aware of the facade and the one-way communication is provided from facade to the subsystem(s). (The mediator pattern is discussed in Chapter 21 of this book).

     
  9. 9.

    It appears to me that to implement a facade pattern, I have to write lots of code. Is this understanding correct?

    Not at all. It depends on the system and corresponding functionalities. For example, in the preceding implementation, if you consider only one type of robot (either Milano or Robonaut), and if you do not want to provide the destruction mechanism of robots, and if you want to ignore the instruction manuals (two static methods in this example), your code size will drop significantly. I have kept all of these for complete illustration purposes.

     
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset