퍼사드 패턴

이종찬·2023년 2월 7일
0
post-custom-banner

📖 퍼사드 패턴?

Facade라는 단어는 앞쪽 정면 이라는 뜻을 가집니다. 퍼사드 패턴은 클래스, 라이브러리, API의 복잡한 시스템에 대한 단순화된 인터페이스를 제공하는 구조적 디자인 패턴입니다. 퍼사드 패턴은 기본 시스템의 복잡성을 숨기고 클라이언트에 단일 통합 인터페이스를 제공합니다. 그러기 위해서는 Facade는 자신이 가지고 있는 각 클래스의 기능을 명확히 알아야 합니다.

🤔 사용해야 하는 이유는?

  • Facade는 클라이언트와 복잡한 시스템 사이에서 중개자 역할을 하여 클라이언트가 간단하고 높은 수준의 인터페이스를 제공하여 시스템을 보다 쉽게 사용할 수 있도록 합니다.
  • 클라이언트가 시스템 각각의 개별 개체가 아닌 Facade는와 상호 작용하기 때문에 느슨한 결합을 촉진합니다. 이로 인해 클라이언트에 영향을 주지 않고 복잡한 시스템을 더 쉽게 유지가 가능합니다.
  • Facade뒤에 개체가 그룹화 되므로 시스템의 응집력을 높입니다.

😮 사용되는 사례

도서관 시스템을 예로 들면, 시스템에는 책, 잡지 등을 관리하는 여러 클래스 및 메서드가 포함된 구조로 되어있습니다. 퍼사드 패턴을 사용할 경우 도서관 시스템에 대한 단순화된 인터페이스를 제공하여 사용자가 복잡성을 고려하지 않고 책, 잡지 등을 쉽게 검색, 대여 등을 액세스 할 수 있게 합니다.

❌ 문제가 되는 경우

  • 복잡한 시스템간의 느슨한 결합을 촉진하지만 Facade와 캡슐화된 개체 간 결합도를 증가 시킬 수도 있습니다. 오히려 수정하거나 교체하기 어려워지는 상황이 올 수 있습니다.

  • Facade는 복잡한 시스템를 단순화된 인터페이스로 제공합니다. 이로 인해 Facade를 이해,유지,관리,수정 등이 어려워져 복잡성이 증가, 모듈성 감소를 유발할 수 있습니다. 더 나아가 단일 책임 원칙 위반으로 이어질 수 있습니다.

👨‍💻 구현

non-facade

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 + " connect");
    }

    public void moveDirectory() {
        System.out.println("FTP Path : "+path+" move");
    }

    public void disConnect() {
        System.out.println("FTP disconnected");
    }
}

Reader, Writer

class Reader {
    private String fileName;

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

    public void fileConnect() {
        String msg = String.format("Reader %s connect", fileName);
        System.out.println(msg);
    }

    public void fileRead() {
        String msg = String.format("Reader %s read", fileName);
    }

    public void fileDisconnect() {
        System.out.println("fileReader disconnected");
    }
}

class Writer {
    private String fileName;

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

    public void fileConnect() {
        String msg = String.format("Writer %s connect", fileName);
        System.out.println(msg);
    }

    public void write() {
        String msg = String.format("writer %s write", fileName);
    }

    public void fileDisconnect() {
        System.out.println("writer disconnected");
    }
}

Main

public class Main {
    public static void main(String[] args) {
        FTP client = new FTP("www.naver.com", 22, "/home/etc");
        client.connect();
        client.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();
        client.disConnect();

    }
}

실행결과

FTP Host : www.naver.com, Port : 22 connect
FTP Path : /home/etc move
Writer text.tmp connect
Reader text.tmp connect
fileReader disconnected
writer disconnected
FTP disconnected


facade pattern apply

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 SftpClient(FTP ftp, String fileName) {
        this.ftp = ftp;
        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) {
        FTP client = new FTP("www.naver.com", 22, "/home/etc");
        SftpClient facade = new SftpClient(client, "text.tmp");

        facade.connect();
        facade.write();
        facade.read();
        facade.disConnect();
    }
}

실행결과

FTP Host : www.naver.com, Port : 22 connect
FTP Path : /home/etc move
Writer text.tmp connect
Reader text.tmp connect
writer disconnected
fileReader disconnected
FTP disconnected

✅ 요약

  • 퍼사드 패턴은 복잡한 시스템에 대한 단순화된 인터페이스를 제공하는 구조적 디자인 패턴
  • 복잡한 구조를 클라이언트가 쉽게 이용할 수 있다.
  • 도서관을 아까 예로 들었지만 가장 적합한 것은 리모컨이 아닐까 싶다. 복잡한 이해 관계 없이 이용자가 버튼을 누르면 복잡한 작업을 다 처리한 이후에 디스플레이에 이벤트에 대한 콜백이 적용되는 것 처럼 말이다.
  • 복잡한 시스템을 단순화된 인터페이스로 제공하는 과정에서 복잡성 증가, 모듈성 감소 단일 책임 원칙 위반까지 이어질 수 있습니다. 잘 고려해서 구현해야합니다.
profile
왜? 라는 질문이 사라질 때까지
post-custom-banner

0개의 댓글