알아두면 쓸데있는 IT 잡학사전

1. 개요

여러가지 복잡한 것들을 하나로 간주해서 편하게 다루는 방법입니다.

예를 들어, 우리가 흔히 자동차라고 하는 물건은 바퀴, 엔진, 오디오, 사이드 미러 등등 으로 이루어져있지만 우리는 그냥 다 자동차라고 생각하는 것이 편합니다. 차안에서 음악을 듣고 싶으면, 그냥 오디오를 켜면 됩니다. "차량에 내장된 오디오"라는 것을 굳이 명확히 하기는 귀찮기 때문입니다.


2. 예제

ㅇㅇㅇ

//----------------- 내부구성품 1. TV ----------
package design.pattern.Facade;
public class TV {
    private boolean turnedOn = false;
    public void turnOn(){
        turnedOn = true;
        System.out.println("TV를 켬.");
    }
    public void turnOff(){
        turnedOn = false;
        System.out.println("TV를 끔.");
    }
    public boolean isTurnedOn(){
        return turnedOn;
    }
}
//----------------- 내부구성품 2. 오디오 ----------
package design.pattern.Facade;
public class Audio {
    private boolean playing = false;
    public void play(){
        playing = true;
        System.out.println("음악을 연주.");
    }
    public void stop(){
        playing = false;
        System.out.println("음악을 멈춤");
    }
    public boolean isPlaying() {
        return playing;
    }
}
//----------------- 내부구성품 3. 전등 ----------
package design.pattern.Facade;
public class Light {
    private int lightness = 0;
    public int getLightness() {
        return lightness;
    }
    public void setLightness(int lightness) {
        System.out.println("밝기를 "+ lightness + "로 변경.");
        this.lightness = lightness;
    }
}
//----------------- Facade ----------
package design.pattern.Facade;
public class Home {
    private Audio audio;
    private Light light;
    private TV tv;
    public Home(Audio audio, Light light, TV tv) {
        this.audio = audio;
        this.light = light;
        this.tv = tv;
    }
    public void enjoyTv(){
        System.out.println("==불을 밝게하고 TV보기.");
        light.setLightness(2);
        tv.turnOn();
    }
    public void enjoyMusic(){
        System.out.println("==불을 약간 어둡게하고 음악듣기.");
        light.setLightness(1);
        audio.play();
    }
    public void goOut(){
        System.out.println("==TV끄고, 음악도 끄고, 불도 끄고 외출하기.");
        if (tv.isTurnedOn()) {
            tv.turnOff();
        }
        if (audio.isPlaying()) {
            audio.stop();
        }
        light.setLightness(0);
    }
}
//----------------- 테스트 클래스 ----------
package design.pattern.Facade;
public class Test {
    public static void main(String[] args) {
        TV tv = new TV();
        Audio audio = new Audio();
        Light light = new Light();
        
        Home home = new Home(audio, light, tv);
        
        home.enjoyTv();
        home.enjoyMusic();
        home.goOut();
    }
}

//----------------- 테스트 결과 ----------
==불을 밝게하고 TV보기.
밝기를 2로 변경.
TV를 켬.
==불을 약간 어둡게하고 음악듣기.
밝기를 1로 변경.
음악을 연주.
==TV끄고, 음악도 끄고, 불도 끄고 외출하기.
TV를 끔.
음악을 멈춤
밝기를 0로 변경.

Test 클래스에서는 TV, Audio, Light 등의 클래스의 인스턴스를 가지고 있긴하지만, Home을 생성하는 용도 외에는 사용하지 않습니다.

TV나 Audio 등이 저차원 클래스라면, Home은 저차원 클래스들을 감싸고 있는 고차원 클래스 입니다. 실질적인 저차원 클래스들의 조합은 바로 고차원 클래스인 Home클래스가 담당합니다. 클라이언트인 Test클래스는 고차원 클래스만 집중합니다.


3. Facade 의 특징

예제에서 굳이 TV, Light, Audio라는 클래스들을 만들지 않고, Home 클래스 안에다가 기능을 다 넣을 수도 있었습니다. 그런데, TV가 꼭 Home에 종속되어야 할까요? 요즘은 핸드폰으로도 TV보는 세상인데요.

Facade 패턴을 사용하면 최소단위로 클래스를 설계할 수 있습니다. 물론, 지나치게 잘게 쪼개는 것도 그다지 바람직하진 않습니다 . 코드를 다른 데에 복사해서 사용하지 않는 선 정도에서 클래스를 분리시키면 될 것 같습니다.

예제코드의 경우 TV를 분리시키지 않는다면 핸드폰 클래스가 나왔을 때, 핸드폰 클래스의 TV기능을 다시 구현해야하는 사태가 발생합니다.


'개발 > JAVA' 카테고리의 다른 글

[Design Pattern]Prototype  (0) 2018.07.16
[Design Pattern]Observer  (0) 2018.07.16
[Design Pattern]Composite  (0) 2018.07.16
[Design Pattern]Composite  (0) 2018.07.16
[Design Pattern]Strategy  (0) 2018.07.16