본문 바로가기
자바

디자인 패턴 6. 파사드 패턴 (Facade Pattern)

by 호놀롤루 2022. 3. 12.

1. 개요

Facade는 건물의 앞쪽 정면이라는 뜻을 가진다. 여러개의 객체와 실제 사용하는 서브 객체의 사이에 복잡한

의존관계가 있을 때, 중간에 facade라는 객체를 두고, 여기서 제공하는 인터페이스만을 활용하여 기능을

사용하는 방식이다.

 

그러므로 Facade는 자신이 가지고 있는 각 클래스의 기능을 명확히 알고 있어야 한다.

 

 

2. 코드

우선 파사드 패턴 없이 사용하는 방식이다.

package com.company.design.facade;

public class Ftp {

    private String host;
    private int port;
    private String path;

    public Ftp(String host, int port, String path) {
        this.host = host;
        this.port = port;
        this.path = path;
    }

    public void connect() {
        System.out.println("FTP Host : " + host + " Port : "+port + " 로 연결합니다.");
    }

    public void moveDirectory() {
        System.out.println("FTP path : "+path+"로 이동합니다.");
    }

    public void disConnect() {
        System.out.println("FTP 연결을 종료합니다.");
    }
}

FTP에서는 host, port, path를 받아서 연결, 이동, 연결 종료의 작업이 가능하다.

 

package com.company.design.facade;

public class Reader {

    private String fileName;

    public Reader(String fileName) {
        this.fileName = fileName;
    }

    public void fileConnect() {
        String msg = String.format("Reader %s 로 연결합니다.", fileName);
        System.out.println(msg);
    }

    public void fileRead() {
        String msg = String.format("Reader %s 의 내용을 읽어옵니다.", fileName);
        System.out.println(msg);
    }

    public void fileDisconnect() {
        String msg = String.format("Reader %s 로 연결 종료합니다.", fileName);
        System.out.println(msg);
    }
}

Reader에서는 fileName을 받아서, 파일과 연결, 읽기, 연결 종료의 작업이 가능하다.

 

package com.company.design.facade;

public class Writer {

    private String fileName;

    public Writer(String fileName) {
        this.fileName = fileName;
    }

    public void fileConnect() {
        String msg = String.format("Writer %s 로 연결합니다.", fileName);
        System.out.println(msg);
    }

    public void fileDisconnect() {
        String msg = String.format("Writer %s 로 연결 종료합니다.", fileName);
        System.out.println(msg);
    }

    public void write() {
        String msg = String.format("Writer %s 로 파일쓰기를 합니다.", fileName);
        System.out.println(msg);
    }
}

Writer에서는 fileName을 받아서, 파일과 연결, 쓰기, 연결 종료의 작업이 가능하다.

 

package com.company.design.facade;

public class Main {
    public static void main(String[] args) {
        Ftp ftpClient = new Ftp("www.naver.com", 22, "/home/etc");
        ftpClient.connect();
        ftpClient.moveDirectory();


        Writer writer = new Writer("text.tmp");
        writer.fileConnect();
        writer.write();

        Reader reader = new Reader("text.tmp");
        reader.fileConnect();
        reader.fileRead();

        reader.fileDisconnect();
        writer.fileDisconnect();
        ftpClient.disConnect();

    }
}

결과

FTP Host : www.naver.com Port : 22 로 연결합니다.
FTP path : /home/etc로 이동합니다.
Writer text.tmp 로 연결합니다.
Writer text.tmp 로 파일쓰기를 합니다.
Reader text.tmp 로 연결합니다.
Reader text.tmp 의 내용을 읽어옵니다.
Reader text.tmp 로 연결 종료합니다.
Writer text.tmp 로 연결 종료합니다.
FTP 연결을 종료합니다.

 

파사드 객체가 없다면, Main에서 연결을 해야하고, 이 코드는 간단하지만 규모가 커질수록 복잡한 의존관계가

생긴다.

 

여기서 파사드 객체 추가

package com.company.design.facade;

public class SftpClient {

    private Ftp ftp;
    private Reader reader;
    private Writer writer;

    public SftpClient(Ftp ftp, Reader reader, Writer writer) {
        this.ftp = ftp;
        this.reader = reader;
        this.writer = writer;
    }

    public SftpClient(String host, int port, String path, String fileName) {
        this.ftp = new Ftp(host, port, path);
        this.reader = new Reader(fileName);
        this.writer = new Writer(fileName);
    }

    public void connect() {
        ftp.connect();
        ftp.moveDirectory();
        writer.fileConnect();
        reader.fileConnect();
    }

    public void disConnect() {
        writer.fileDisconnect();
        writer.fileDisconnect();
        ftp.disConnect();
    }

    public void read() {
        reader.fileRead();
    }

    public void write() {
        writer.write();
    }

}

SftpClient는 생성자를 오버로딩해서 2가지를 받을 수 있다.

만약 생성자에서 host, port, path, fileName을 집어넣는다면 ftp, reader, writer를 초기화하는 것이 가능하다.

 

connect()에선 ftp 연결, 디렉토리 이동, writer 연결, reader 연결 의 작업을 수행해준다.

 

disConnect() 에선 위에서 위에서 연결한 걸 다 끊어준다.

 

read()에선 파일을 읽고, write()에선 파일에 입력을 한다.

 

package com.company.design.facade;

public class Main {
    public static void main(String[] args) {
        Ftp ftpClient = new Ftp("www.naver.com", 22, "/home/etc");
        ftpClient.connect();
        ftpClient.moveDirectory();


        Writer writer = new Writer("text.tmp");
        writer.fileConnect();
        writer.write();

        Reader reader = new Reader("text.tmp");
        reader.fileConnect();
        reader.fileRead();

        reader.fileDisconnect();
        writer.fileDisconnect();
        ftpClient.disConnect();

        SftpClient sftpClient = new SftpClient("www.naver.com", 22, "/home/etc", "text.tmp");

        sftpClient.connect();

        sftpClient.write();

        sftpClient.read();

        sftpClient.disConnect();

    }
}

파사드 패턴을 이용한 결과, 의존성을 SftpClient가 다 가져갔고, StfpClient에서 기능을 제공한다.

 

각각의 객체에 의존하기 보다, 파사드 객체를 통해 Main에서 간략한 코드를 쓸 수 있다.

댓글