[Java] Facade Pattern

이의찬·2022년 8월 31일

Java

목록 보기
1/3

Facade는 건물의 앞쪽 정면이라는 뜻을 가진다. 여러 개의 객체와 실제 사용하는 서브 객체의 사이에 복잡한 의존관계가 있을 때, 중간에 facade라는 객체를 두고, 여기서 제공하는 interface만을 활용하여 기능을 사용하는 방식이다. Facade는 자신이 가지고 있는 각 클래스의 기능을 명확히 알아야 한다.
코딩할 때 자주 사용하고 여러 개의 객체를 합쳐서 하나의 기능으로 만들 때 사용한다.

ftp 통신을 예로 파일을 쓰고 읽는 예제로 알아보자.

Ftp

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("path: " +path +" 로 이동");
    }
    public void disConnect() {
    	System.out.println("연결 종료");
    }
}

Writer

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 wirte() {
    	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);
    }
}

Reader

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);
    }
}

Main


public class Main {
	public static void main(String[] args) {
    	Ftp ftpClient = new Ftp("www.foo.co.kr", 22, "/home/etc"); // host, port, path
        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();        
    }
}

facade 패턴을 사용하지 않을때는 모든 객체가 각자 연결하고 일을 수행한다음 각자 연결을 끊어야 한다.

이를 facade 패턴으로 모든 의존성을 SftpClient 클래스 안으로 넣는다.

SftpClient

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();
        reader.fileDisconnect():
        ftp.disConnect();
    }
    
    public void read() {
    	reader.fileRead();
    }
    
    public void write() {
    	writer.write();
    }
}

메인 코드를 바꿔보자

Main


public class Main {
	public static void main(String[] args) { 
        SftpClient sftpClient = new SftpClient("www.foo.co.kr", 22, "/home/etc", "text.tmp");
        sftpClient.connect();
        sftpClient.write();
        sftpClient.read();
        sftpClient.disConnect();
    }
}

각각의 객체에 의존하는 것보다 Facade 패턴을 통해 마치 건물의 정면만 바라보는 형태의 객체가 만들어지고 복잡한 의존성을 가진 것들을 새로운 인터페이스 형태로 제공함으로써 코드를 간략하게 줄일 수 있다.

0개의 댓글