Facade 패턴

2020-04-08

Facade 패턴

Facade 패턴은 GoF에 따르면 "서브시스템에 있는 인터페이스들을 통합 인터페이스로 제공해주는 것" 입니다. Facade 패턴은 서브시스템이 쉽게 사용할 수 있도록 하이레벨의 인터페이스를 제공해줍니다.

여기서 인터페이스는 자바의 인터페이스를 말하는 것이 아닙니다.

예를 들어 Mysql과 Oracle 데이터베이스를 사용하여 문서를 HTML 또는 PDF로 만드는 인터페이스들이 있다고 가정해봅시다.데이터베이스 타입에 따라 다르게 작동하는 인터페이스들이 생기게 됩니다. 이 인터페이스들을 클라이언트가 사용하게 됩니다.

그러나 그 인터페이스들이 복잡성이 증가되거나, 인터페이스 이름이 헷갈리게 되면, 클라이언트에서는 이를 관리하기가 어려워 집니다. 그래서 Facade 패턴은 이 인터페이스들을 묶어서 클라이언트가 쉽게 사용할 수 있도록 도와줍니다.

인터페이스들 만들기

MySqlHelper 클래스

import java.sql.Connection;

public class MySqlHelper {

    public static Connection getMySqlDBConnection(){
        //Connection을 이용해서 Mysql 연결 맺기
        return null;
    }

    public void generateMySqlPDFReport(String tableName, Connection con){
        // 테이블에서 데이터를 가져와 pdf 만들기
    }

    public void generateMySqlHTMLReport(String tableName, Connection con){
        // 테이블에서 데이터를 가져와 html 만들기
    }
}

OracleHelper 클래스

import java.sql.Connection;

public class OracleHelper {

    public static Connection getOracleDBConnection(){
        //Connection을 이용해서 Oracle 연결 맺기
        return null;
    }

    public void generateOraclePDFReport(String tableName, Connection con){
        // 테이블에서 데이터를 가져와 pdf 만들기
    }

    public void generateOracleHTMLReport(String tableName, Connection con){
        // 테이블에서 데이터를 가져와 html 만들기
    }

}

Facade 인터페이스

HelperFacade 클래스

import java.sql.Connection;

public class HelperFacade {
    public static void generateReport(DBTypes dbType, ReportTypes reportType, String tableName){
        Connection con = null;
        switch (dbType){
            case MYSQL:
                con = MySqlHelper.getMySqlDBConnection();
                MySqlHelper mySqlHelper = new MySqlHelper();
                switch(reportType){
                    case HTML:
                        mySqlHelper.generateMySqlHTMLReport(tableName, con);
                        break;
                    case PDF:
                        mySqlHelper.generateMySqlPDFReport(tableName, con);
                        break;
                }
                break;
            case ORACLE:
                con = OracleHelper.getOracleDBConnection();
                OracleHelper oracleHelper = new OracleHelper();
                switch(reportType){
                    case HTML:
                        oracleHelper.generateOracleHTMLReport(tableName, con);
                        break;
                    case PDF:
                        oracleHelper.generateOraclePDFReport(tableName, con);
                        break;
                }
                break;
        }

    }

    public static enum DBTypes{
        MYSQL,ORACLE;
    }

    public static enum ReportTypes{
        HTML,PDF;
    }
}

클라이언트 코드

FacadePatternTest 클래스

import java.sql.Connection;

public class FacadePatternTest {
    public static void main(String[] args) {
        String tableName="Employee";

        //Facade 패턴 안씀
        Connection con = MySqlHelper.getMySqlDBConnection();
        MySqlHelper mySqlHelper = new MySqlHelper();
        mySqlHelper.generateMySqlHTMLReport(tableName, con);

        Connection con1 = OracleHelper.getOracleDBConnection();
        OracleHelper oracleHelper = new OracleHelper();
        oracleHelper.generateOraclePDFReport(tableName, con1);

        //Facade 패턴 씀
        HelperFacade.generateReport(HelperFacade.DBTypes.MYSQL, HelperFacade.ReportTypes.HTML, tableName);
        HelperFacade.generateReport(HelperFacade.DBTypes.ORACLE, HelperFacade.ReportTypes.PDF, tableName);
    }
}

보시다시피 Facade 패턴을 이용하면 클라이언트 사이드에서 많은 로직을 피하고 쉽고 깔끔한 방법을 사용할 수 있습니다.

JDBC Driver Manager 클래스가 완벽한 facade 디자인 패턴의 예입니다.

Facade 패턴의 중요한 부분

  • Facade 패턴은 클라이언트를 좀 더 도와주는 패턴입니다. 클라이언트로부터 서브시스템의 인터페이스들을 숨기지 않습니다. Facade 패턴을 쓰는건 온전히 클라이언트 측에 달려 있습니다.
  • Facde 패턴은 개발 어느 부분이든지 적용할 수 있습니다. 대부분 인터페이스들이 많아지거나, 시스템이 복잡해질 때 사용합니다.