본문 바로가기

소프트웨어/디자인패턴

[소프트웨어/디자인패턴] 퍼사드 패턴 (Facade Pattern)

컴퓨터의 전원버튼을 누를때 우린 어떻게 동작하는지 생각하지 않는다.

글을 작성하려고 준비하면서 느낀점은 "과연 이 게시글을 볼까?"였다. 너무 쉬웠기떄문이다. 복잡한 프로세스의 내용을 하나의 인터페이스 메서드로 간략화하여 사용하는 패턴으로 정리할 수 있다.

Context

주인공은 쉬는 동안에 영화를 보고싶다. 집에 DVDPlayerScreen이 있어 이를 사용하여 영화관에 가지 않고도 충분히 좋은 환경으로 영화를 즐긴다.


주인공이 쉴때 영화를 보려면 screen.on() -> dvdPlayer.insert()순으로 스크린을 켜고 볼 영화의 DVD를 플레이어에 넣어야한다.

이와 같은 내용을 코드드로 나타내면 아래와 같다.

class Screen {
    public void on() {
        System.out.println("Screen on");
    }

    public void off() {
        System.out.println("Screen out");
    }
}

class DVDPlayer {
    public void insert() {
        System.out.println("insert dvd to player...");
    }

    public void remove() {
        System.out.println("remove dvd from player");
    }
}

class ClientA {
    public void rest() {
        Screen screen = new Screen();
        DVDPlayer dvdPlayer = new DVDPlayer();

        screen.on();
        dvdPlayer.insert();
    }

    // 실행 코드
    public static void main(String[] args) {
        ClientA client = new ClientA();
        client.rest();
    }
}

Problem

주인공은 스크린에 포함된 내장 스피커로는 만족을 느끼지 못한다. 그래서 인지 어느날 외부 Speaker를 사게 된다.

영화를 볼때마다 기존의 프로세스에서 하나가 추가된다. 스크린을 켜고 -> 플레이어에 DVD를 넣고 -> 스피커를 킨다. 사실 주인공의 입장에선 매번 이런 반복적인 프로세스를 진행하는 것은 굉장히 귀찮은 일일 것이다.

class Speacker {
    public void on() {
        System.out.println("Speaker on");
    }

    public void off() {
        System.out.println("Speaker off");
    }
}

class ClientA {
    public void rest() {
        Screen screen = new Screen();
        DVDPlayer dvdPlayer = new DVDPlayer();
        Speacker speacker = new Speacker();

        screen.on();
        dvdPlayer.insert();
        speacker.on();
    }
}

전 세계에는 사람이 참 많다, 그래서 ClientB는 취미가 집에서 영화를 보는 것이다. ClientA가 휴식할 때와 동일한 내용을 취미로 사용하는 것이다.

class ClientB {
    public void hobby() {
        Screen screen = new Screen();
        DVDPlayer dvdPlayer = new DVDPlayer();
        Speacker speacker = new Speacker();

        screen.on();
        dvdPlayer.insert();
        speacker.on();
    }
}

위와 같은 코드가 탄생하게 되는데 ClientArest와 동일하다.

Solution

이러한 중복코드와 반복적으로 실행될 필요가 없는 코드를 한 클래스WatchInterface의 메서드watchMovie로 모아 공개한다.

class WatchInterface {
    private Speacker speacker = new Speacker();
    private Screen screen = new Screen();
    private  DVDPlayer dvdPlayer = new DVDPlayer();

    public void watchMovie() {
        screen.on();
        dvdPlayer.insert();
        speacker.on();
    }
}

class ClientB {
    public void hobby() {
        WatchInterface watchInterface = new WatchInterface();
        watchInterface.watchMovie();
    }
}

class ClientA {
    public void rest() {
        WatchInterface watchInterface = new WatchInterface();
        watchInterface.watchMovie();
    }
}

이를 통해 사용자는 영화를 볼떄 어떠한 프로세스가 필요한지, 어떠한 기기를 켜고 끄는지에 대한 내용을 알 필요가 없게 되었다.

Summary

Facade는 건물의 외관을 뜻하는데 이는 복잡한 내부를 볼 필요없이 잘 정돈된 모양을 의미한다. API를 호출할 떄 내부의 서브 패키지가 어떻게 호출되는지 사용자는 몰라도 되는 부분에 대해서 잘 정리하여 감싸는데 이는 캡슐화의 의미가 아니다.

사용자는 얼마든지 서브 패키지, 클래스에 접근이 가능하지만 자주 사용하고 반복하여 작성할 필요 없는 코드에 대해서 정리 한다는 의미이다.