Facade는 건물의 앞쪽정면이라는 뜻이다.
여러개의 객체와 실제 사용하는 서브 객체의 사이에 복잡샇ㄴ 의존관계가 있을때, 중간에 facade라는 객체를 두고, 여기에서 제공하는 interface만을 활용하여 기능을 사용하는 방식이다.
Facade는 자신이 가지고 있는 각 클래스의 기능을 명확하게 알아야 한다.
Facade패턴 없이 FTP 사용을 예로 작성
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연결을 종료 합니다.");
}
}
파일을 읽는 클래스 작성
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 disConnect() {
String msg = String.format("Reader %s 로 연결 종료 합니다.",fileName);
System.out.println(msg);
}
}
파일을 쓰는 클래스 작성 해준다.
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 write(){
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);
}
}
FTP를 가상으로 주소및 호스트 파일 경로 를 입력하여 연결하고 파일을 읽고 쓴 후 종료 까지하는 내용을 작성 해본다.
현재는 클라이언트 (main)가 의존성을 가지고 만들고 출력되고 있다.
public class main {
public static void main(String[] args) {
Ftp ftpClient = new Ftp("www.foo.co.kr",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.fileConnect();
writer.fileConnect();
ftpClient.disConnect();
}
}
모든 객체의 의존성을 갖는 facade 패턴의 객체를 만들어 새로운 인터페이스를 제공하여 준다.
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() { // 새로운 4가지의 인터페이스 제공
ftp.connect();
ftp.moveDirectory();
writer.fileConnect();
reader.fileConnect();
}
public void disConnect() {
writer.fileDisconnect();
reader.fileDisconnect();
ftp.disConnect();
}
public void read(){
reader.fileRead();
}
public void writer(){
writer.write();
}
}
아래와 같이 클라이언트 (main)가 각각의 객체에 의존성을 갖는게 아닌 앞쪽만 바라보는 facade패턴의 객체를 사용하여
복잡한 여러가지 의존성을 가진 객체를 새로운 인터페이스로 사용할 수 있다. 외부에서는 간략하게 코드를 줄일 수 있고 기능은 그대로 사용 할 수 있다.
public class main {
public static void main(String[] args) {
SftpClient sftpClient = new SftpClient("www.foo.co.kr", 22, "/home/ect" , "text.tmp");
sftpClient.connect();
sftpClient.writer();
sftpClient.read();
sftpClient.disConnect();
}
}