[Java] What is the Facade pattern useful for?

2 minute read

Purpose

Briefly explain what the Facade pattern is useful for (with code)

How useful is the Facade pattern?

Simply put, ** a coordinator for multiple processes **.
Therefore, it is useful in that it does various jobs with one request.

Facade pattern requirements

–The Facade class only throws work inside the subsystem and does not have a complicated implementation.
–The Facade class is never used by the subsystem itself.
–The Facade pattern does not interfere with the direct use of subsystems.

Class diagram

Facade pattern class diagram

image.png

Source: Wiki –Facade pattern

Class diagram of the code explained this time

image.png
It is a specification from the standpoint that Librarian has BookList and LendingList, and there is no change in the implementation itself of using it as a window.

Each role in the class diagram

Facade: Librarian class
Subsystem: BookList class, LendingList class
Client: Visitor class

Involvement of each class

–Librarian (librarian) can take on the role of searching for books.
–Visitors can ask the Librarian to search for books, or they can search for them themselves.
–BookList and LendingList are used by Librarian or Visitor.

code

Librarian.java


package facade;

//librarian
public class Librarian {
    private BookList _bookList;
    private LendingList _lendingList;

    Librarian(BookList bookList, LendingList lendingList){
        _bookList = bookList;
        _lendingList = lendingList;
    }

    public String searchBook(String bookName) {
        //Is it in the possession?
        if(!_bookList.existsBook(bookName)) return "The book is not in the possession";

        //Is it on the bookshelf?
        if (_lendingList.isLending(bookName)) return "Lending";

        //Collection location
        return _bookList.searchLocation(bookName);
    }
}

BookList.java


package facade;

import java.util.HashMap;
import java.util.Map;

//Collection book ledger
public class BookList {
    private Map<String, String> _record = new HashMap<String, String>();

    public void addRecord(String bookName, String locationName) {
        _record.put(bookName, locationName);
    }

    public boolean existsBook(String bookName) {
        return _record.containsKey(bookName);
    }

    public String searchLocation(String bookName) {
        return (String)_record.get(bookName);
    }
}

LendingList.java


package facade;

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

//Lending book
public class LendingList {
    private List<String> _record = new ArrayList<String>();

    public void lending(String bookName) {
        _record.add(bookName);
    }

    public void returned(String bookName) {
        _record.remove(bookName);
    }

    public boolean isLending(String bookName) {
        return _record.contains(bookName);
    }
}

Visitor.java


package facade;

public class Visitor {
    private String _name;
    private String _targetBookName;

    Visitor(String name){
        _name = name;
    }

    public void setTargetBookName(String targetBookName) {
        _targetBookName = targetBookName;
    }

    public String targetBookName() {
        return _targetBookName;
    }

    public String name() {
        return _name;
    }
}

Main.java


package facade;

import java.io.PrintStream;

public class Main {
    public static void main(String[] args) {
        //Initial value set
        // (Collection list)
        BookList bookList = new BookList();
        bookList.addRecord("Insect picture book", "Shelf number 1");
        bookList.addRecord("Animal picture book", "Shelf number 1");
        bookList.addRecord("Momotaro", "Shelf number 2");
        bookList.addRecord("Kintaro", "Shelf number 2");
        bookList.addRecord("How the computer works", "Shelf number 3");
        bookList.addRecord("Java programming", "Shelf number 3");
        // (Lending list)
        LendingList lendingList = new LendingList();
        lendingList.lending("Insect picture book");
        lendingList.lending("Momotaro");
        lendingList.lending("How the computer works");

        PrintStream out = System.out;

        //user[Yamada-kun]:librarian[Nakamura-kun]When requesting
        Visitor yamada = new Visitor("Yamada");
        yamada.setTargetBookName("Insect picture book");
        // (Window[Nakamura-kun])
        Librarian nakamura = new Librarian(bookList, lendingList);
        // (Ask Nakamura-kun about the location of the insect picture book)
        out.println(yamada.name() + "Result:");
        out.println(nakamura.searchBook(yamada.targetBookName()));
        out.println();

        //user[Kinoshita-kun]: When searching by yourself
        Visitor kinoshita = new Visitor("Kinoshita");
        kinoshita.setTargetBookName("Animal picture book");
        if(!bookList.existsBook(kinoshita.targetBookName())) {
            out.println("Let's make another book");
            return;
        }
        if(lendingList.isLending(kinoshita.targetBookName())) {
            out.println("Let's make another book");
            return;
        }
        out.println(kinoshita.name() + "Result:");
        out.println(bookList.searchLocation(kinoshita.targetBookName()));
        out.println();
    }
}

Please change the targetBookName of Yamada-kun and Kinoshita-kun and check the operation.

Github
https://github.com/TakumiKondo/designpattern/tree/master/src/facade/librarian

Where to use

Once you start writing a series of code that calls multiple processes in various places,
Consider using the Facade pattern.

However, as required, it should not contain complex logic.
To the last, it is required to devote itself to the role of bundling processing.

reference

Facade pattern
https://ja.wikipedia.org/wiki/Facade_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

Source of code (modified based on this)
https://www.techscore.com/tech/DesignPattern/Facade.html/