[Proxy패턴] 큰 데이터를 로딩하는데 써라~

2007. 8. 16. 08:49Java

Proxy 패턴

이번에는 Proxy 패턴입니다. 항상 패턴을 논할때, 제일 먼저 생각해야 할 것이 바로.
언제 이 패턴을 쓰면 좋을까 입니다. 솔직히 이패턴도 별거 아닙니다. 대부분의 개발자분들이 많이 써왔고,
많이 아시는 부분이죠. Proxy의 의미는 말그대로 대리자 or 대리인입니다.

대리라.. 먼가를 대신 해준다는 거죠.
일을 넘겨서 먼가를 하라는

"이거좀 해주세요" - 의뢰인
" 네 맡겨만 주세요. 다른일부터 하십시오. 완성되면 알려드리겠습니다." - 대리인

위의 말처럼 먼가를 맡기면 그 일을 처리하고 완료되면 그 결과를 알려주는게 바로 Proxy패턴입니다.
Proxy패턴의 유형에는 여러가지만 있지만, 여기서는 제일 많이 사용하는 것에만 설명하겠습니다.
( 다른 유형은 거의 쓰지 않게 되더군요. ㅋㅋ )

자자, 어떤 게임 화면을 생각해 봅시다. 간단한 시나리오 입니다.

1. 게임 중앙에는 어떤 큰 데이터를 로딩해서 사람 모형의 3D 그래픽을 연출해야합니다.
2. 게임 화면 주변에는 간단한 기본 UI,채팅창, 아이콘들이 배치되어야 합니다.

자 이제 위의 1,2번을 수행해야 하는 화면을 로딩해 봅시다.
10메가 분량의 모형 3d데이터와 10k의 ui이미지를 로딩해야합니다. 한번에 로딩해서 화면에 보여줍니다.

시스템 메시지 : 10초뒤에 로딩됩니다. 기다리세요.
유저: "아놔 욘니 오래 걸리네."

자 왜이럴까요. 제일큰문제점은, 큰 데이터를 로딩하는데 많은 시간이 걸린다는 겁니다.
그럼 어떻게 처리해야 할까요.
다음과 같은 방식은 어떻습니까.

1. 작은 이미지나, 채팅창부터 로딩한다. (유저는 기다리지않고 바로 여러기능을 쓸 수 있다.)
2. 큰데이터는 스레드로 돌려서 다 로딩되면 그때 중앙에 보여준다.

이제, 유저는 이 화면을 로딩하면, 바로 기다리지않고 다른 여타기능을 이용할 수 있습니다. 단지 중앙에는 빈화면이 나오겠지요.(대부분의 유저는 이것은 이해합니다.) 데이터가 다 로딩되면 중앙에 3d그래픽이 나옵니다.

이게 바로 Proxy 패턴입니다. 큰데이터는 스레드를 이용해서 따로 로딩하면서 완료될때까지 기다리고,
다른 스레드는 작은 이미지부터 로딩해서 보여줍니다.

즉,
"큰 데이터는 스레드를 통해 로딩하면서 다른일을 수행한다."
"고객을 기다리게 하지말자."
가 요점 입니다.

아래는 간단히 짜본 소스입니다.
package test;

interface Loader {
    public Data getData();
}
// 결과 데이터
class Data{
    public String msg;
    public boolean isLoaded() { return msg==null? false:true; } //로딩이 완료되었는가.
}
// 큰 데이터를 스레드로 로딩하고, 로딩이 완료되면 결과를 리턴합니다.
class DataLoader implements Loader{
    private Data data = new Data();
    public Data getData() {
        new Thread(){
            public void run() {
                // 데이터를 로딩하는데 5초가 걸린다고 가정함.
                for(int i=0; i<5; i++) {
                    try {
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                data.msg = "로딩된 데이터";        
            }

        }.start();
        return data;
    }
}
// 데이터 로더를 대신해서 일을 수행한다.
class TestProxy implements Loader{
    DataLoader loader;
    public Data getData() {
        if(loader==null) loader = new DataLoader();
        return loader.getData();
    }
}

// 실행 클래스.
public class Test {
    public static void main(String[] args) {
        
        TestProxy tp = new TestProxy();
        System.out.println("대리인에게 로딩 요청.");
        Data data = tp.getData();
        System.out.println("작은일을 수행한다. 큰데이터는 로딩완료를 대기한다.");
        while(data.isLoaded()==false) { // 대기            
        }
        // 로딩완료.
        System.out.println("로딩 완료="+data.msg);
    }

}


이렇게 위와같이 수행하면, 로딩하는데 5초가 걸리는 작업은
대리인에게 맡겨놓고,
다음일을 수행합니다. 이제 유저는 기다리지 않아도 되는거죠.

다음에는,, FlyWeight패턴에 대해서 한번 써볼까합니다.
이렇게 써보면서 저도 다시한번 머리속이 정리되네요. ^^

by ncanis(조성준)