Facade Design Pattern

 The Facade pattern is a Structural design pattern that provides a simple interface to hide the complex system underneath. It reduces dependencies to the client into a simplified interface. The client does not see what’s “under the hood” by reducing the dependencies into a simplified interface.

Facade makes APIs easier to use. Examples include a database connection API such as JDBC or a Redis caching service. You can create the underlying system to handle all of the logic that interacts with the database. Then you can have a Facade class that is called from client to Add, Update, or Select data from the database.

Let’s look at a simple implementation that allows the Client to view Upperbody and LowerBody workouts.

Here we are going to create a Workout interface with methodssetWorkout() and viewWorkout() and concrete classes LowerBody and UpperBody.  We then add the WorkoutFacade which interfaces the Workout implementations. The Client has no idea about the LowerBody and UpperBody classes. It just knows the two methods in WorkoutFacade, viewUpperBodyWorkout() and viewLowerBodyWorkout(). Let’s look at each class step by step.

  1. Create the Workout interface.
public interface Workout {

    void setWorkout();

    void viewWorkout();
}
  1. Create a simple Exercise class that contains an id and name. This is to store the exercises as an object.
public class Exercise {
    private int id;

    private String name;

    public Exercise(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

}
  1. Create the Concrete classes LowerBody and UpperBody that inherit Workout. In the setWorkout method we are adding hard coded exercises to a list. In viewWorkout(), we run an enhanced for loop and print out the Exercises names.

import java.util.ArrayList;
import java.util.List;

public class LowerBody implements Workout {

    private List<Exercise> exercises = new ArrayList<>();

    /**
     * Add lower body exercises to an ArrayList
     */
    @Override
    public void setWorkout() {
        exercises.add(new Exercise(1, "Squats"));
        exercises.add(new Exercise(2, "Calf raises"));
        exercises.add(new Exercise(3, "Lunges"));
    }

    /**
     * Loop through the list of exercises and print them out
     */
    @Override
    public void viewWorkout() {
        System.out.println("LowerBody Workout");
        for(Exercise exercise : exercises){
            System.out.println("Exercise: " + exercise.getName());
        }
    }
import java.util.ArrayList;
import java.util.List;

public class UpperBody implements Workout {

    private List<Exercise> exercises = new ArrayList<>();

    /**
     * Add upper body exercises to an ArrayList
     */
    @Override
    public void setWorkout() {
        exercises.add(new Exercise(1, "Bench Press"));
        exercises.add(new Exercise(2, "Push Ups"));
        exercises.add(new Exercise(3, "Inline Bench Press"));
    }

    /**
     * Loop through the list of Exercises and print them out
     */
    @Override
    public void viewWorkout() {
        System.out.println("UpperBody Workout");
        for(Exercise exercise : exercises){
            System.out.println("Exercise: " + exercise.getName());
        }
    }
}
  1. Create the WorkoutFacade class that will hide all of the logic from the Client. Here we create viewUpperBodyWorkout and viewLowerBodyWorkout that will call setWorkout and viewWorkout. The client does not access Workout, UpperBody, or LowerBody.
public class WorkoutFacade {

    /**
     * Creates an instance of UpperBody and calls setWorkout() and viewWorkout()
     */
    public void viewUpperBodyWorkout() {
        Workout workout = new UpperBody();
        workout.setWorkout();
        workout.viewWorkout();
    }

    /**
     * Creates an instance of LowerBody and calls setWorkout() and viewWorkout()
     */
    public void viewLowerBodyWorkout() {
        Workout workout = new LowerBody();
        workout.setWorkout();
        workout.viewWorkout();
    }
}
  1. Last but not least, we will create the WorkoutClient. We create an instance of WorkoutFacade and call viewUpperBodyWorkout() and viewLowerBodyWorkout(). This will produce the following output.
public class WorkoutClient {

    public static void main(String[] args){
        WorkoutFacade workoutFacade = new WorkoutFacade();

        workoutFacade.viewUpperBodyWorkout();
        System.out.println();
        workoutFacade.viewLowerBodyWorkout();
    }
}
UpperBody Workout
Exercise: Bench Press
Exercise: Push Ups
Exercise: Inline Bench Press

LowerBody Workout
Exercise: Squats
Exercise: Calf raises
Exercise: Lunges