The Proxy Pattern

    Proxy 패턴은 간단한 객체로 복잡한 객체를 표현하고자 할 때 사용되어진다. 만약 어떤 객체를 생성하는 것이 시간적으로나 컴퓨터 자원적으로 비용이 많이 든다면 , Proxy는 실제적인 객체를 필요로 할 때까지 객체 생성을 연기하도록 할 것이다.  일반적으로 Proxy는 표현하고자 하는 객체와 같은 메소드를 갖고, 일단 객체가 로드되면, 그것은 Proxy에서 실제적인 객체의 메소드로 바뀌게 된다. 

    Proxy 가 유용하게 사용되어 질 수 있는 유용한 경우는 다음과 같다 :      
  1. 커다란 이미지와 같은 객체가 로드하는데 시간이 많이 걸린다면 Proxy가 유용한다.
  2. 원격 머신에 객체가 있고 그 객체를 네트워크를 통하여 로드하는데 느릴 수 있고, 특히나 로드하는 동안 네트워크 상태가 절정이라면 Proxy가 유용하다.
  3. 객체가 바로 접근하는 것이 제한되어 있다면 Proxy는 사용자의 접근허용을 검증할 수 있다.
    Proxy 들은 또한 객체의 인스턴스 요청과 실제적으로 접근하는 것이 필요한가 사이를 구별하는데 사용되어 질 수 있다. 예를 들어 프로그램 초기화는 바로 사용되어 지지 않는 객체들을 설치할 수 있다. 이 경우에, proxy는 필요할 때만 실제적인 객체를 로드할 수 있다. 

    커다란 이미지를 로드하고 나타내어야 할 필요가 있는 프로그램의 경우를 고려해 보자.  프로그램이 시작될 때 이미지가 스크린에 정확하게 배치될 수 있도록 나타내 줄 수 있는 어떤 필요한 조치를 해야 한다.그러나 실제적인 이미지의 디스플레이는 이미지가 완벽하게 로드될 때까지 지연된다. 이것은 이미지가 이용되기 전에 이미지 주위에 텍스트를  배치하는 워드프로세서나 웹브라우저에서는 상당히 중요하다. 

    이미지 proxy는 이미지를 주목할 수 있고 배경에 이미지를 로딩할 수 있다. 반면에 간단한 사각형이나 다른 기호 같은 것은 그려줄 수 있다. proxy는 paint 요청이 있을 때 까지 이미지를 로딩을 지연하고, paint가 요청될 때만 로딩하게 할 수 있다.

Sample Code

    예제 프로그램에서, 우리는 이미지가 로딩 했을 때 JPanel 상에 이미지를 나타내는 프로그램을 작성하였다. 이미지를 직접적으로 로딩하는 것 보다, 우리는 로딩을 연기하고 이미지가 완벽하게 로딩될 때 까지 이미지 영역에 사각형을 그려주는 ImageProxy라 불리는 클래스를 사용할 것이다. 
	
public class ProxyDisplay extends JxFrame {
	public ProxyDisplay() {
		super("Display proxied image");
		JPanel p = new JPanel();
		getContentPane().add(p);
		p.setLayout(new BorderLayout());
		ImageProxy image = new ImageProxy("elliott.jpg", 321, 271);
		p.add("Center", image);
		p.add("North", new Label("    "));
		p.add("West", new Label("  "));
		setSize(370, 350);
		setVisible(true);
	}
    단지 하나의 이미지를 포함할 수 있는 ImageProxy의 인스턴스를 생성하였고, 실제적인 이미지로써 JPanel을 추가하였다.

    ImageProxy 클래스는 이미지 로딩을 set up 하고, 생성자 내부에서 로딩 처리를 하기 위해 MediaTracker object를 생성하였다.
	

class ImageProxy extends JPanel implements Runnable {
	int height, width;
	MediaTracker tracker;
	Image img;
	JFrame frame;
	Thread imageCheck;        //to monitor loading
	
	//------------------------------------
	
	public ImageProxy(String filename, int w, int h) {
		height = h;
		width = w;
		
		tracker = new MediaTracker(this);
		img = Toolkit.getDefaultToolkit().getImage(filename);
		tracker.addImage(img, 0);     //watch for image loading
		
		imageCheck = new Thread(this);
		imageCheck.start();           //start 2nd thread monitor
		
		//this begins actual image loading
		try {
			tracker.waitForID(0,1);
		}
		catch(InterruptedException e){
		}
}
    MediaTracher 의 weightForID 메소드는 실제적인 로딩 초기화를 한다. 이 경우에, 우리는 프로그램이 지연되는 최소로 하기 위해 최소 기다리는 시간을 1 msec로 입력하였다.

    생성자는 또한 2~3 밀리세컨드에서 로딩 상태를 체크하는 imageCheck 쓰레드를 분리하여 생성하였고, 쓰레드 작동을 시작하였다.
	
public void run() {
	//this thread monitors image loading
	//and repaints when done
	//the 1000 msec is artifically long
	//to allow demo to display with delay
	
	try {
		Thread.sleep(1000);
		while(! tracker.checkID(0))
		Thread.sleep(1000);
	}
	
	catch(Exception e){}
	
	repaint();
}
    마지막으로, Proxy는 JPanel 컴포넌트로부터 파생되었으므로, 본질적으로 paint 메소드를 갖는다. 이 메소드에서, 우리는 이미지 로딩되지 않았다면 사각형을 그려준다. 만약 이미지가 로딩되었다면, 우리는 사각형을 지워주고 대신 이미지를 그릴 것이다.  
	

public void paintComponent(Graphics g) {
	super.paintComponent(g);
	if (tracker.checkID(0)) {
		height = img.getHeight(frame);   //get height
		width = img.getWidth(frame);     //and width
		
		g.setColor(Color.lightGray);     //erase box
		g.fillRect(0,0, width, height);
		g.drawImage(img, 0, 0, this);   //draw loaded image
	}
	else {
		//draw box outlining image if not loaded yet
		g.setColor(Color.black);
		g.drawRect(1, 1, width-2, height-2);
	}
}

    프로그램의 두 가지 상태는 아래의 그림처럼 설명될 수 있다.

        ##########0*##########1*

Copy-on-Write

또, proxy는 변경될 수도 있고, 변경되지 않을 수도 있는 커다란 객체들을 복사하는데에도 사용되어 질 수 있다. 마약 비싼 객체의 두 번째 인스턴스를 생성한다면, Proxy는 여전히 복사본을 만들 이유가 없다는 것을 결정할 수 있다. 간단하게 워본 객체를 사용하는 것이다. 그리고 나서, 만약 프로그램이 새로운 복사로 변경되었다면, Proxy가 원본 객체를 복사할 수 있고, 새로운 인스턴스로 변경되는 것을 만들 수 있다. 이것은 객체들이 인스턴스가 된 후 항상 변경하지 않을 때 시간과 공간을 크게 줄일 수 있게 한다. 

'Development > 패턴자료' 카테고리의 다른 글

[펌] The State Pattern  (0) 2011.08.13
[펌] The Singleton Pattern  (0) 2011.08.13
[펌] The Prototype Pattern  (0) 2011.08.13
[펌] The Observer Pattern  (0) 2011.08.13
[펌] The Memento Pattern  (0) 2011.08.13
안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스
,