본문 바로가기

Domain/디자인패턴

[디자인패턴] 프록시 패턴(Proxy Pattern)

프록시 패턴(Proxy Pattern)

프록시 패턴은 어떤 다른 객체로의 접근하는 것을 제어하기 위해 그 객체의 대리자의 역할을 제공하는 패턴을 의미한다. 프록시 패턴은 다음과 같은 경우에 주로 사용된다.

  1. 한 객체가 너무 일이 많아 대리인 객체가 일부 일을 처리해야할 때
  2. 한 객체를 은닉하고 대리인 객체를 앞으로 먼저 보여야할 때 (Placeholder의 역할)
  3. 사용 여부가 불확실 한 객체를 생성하는 것을 방지하고 실제 필요할 때 생성할 수 있게끔 할 때 --> 영상 썸네일

 

매우 간단한 구현 예시

interface Service{
	fun doSomething()
}

open class MainService: Service{
	override fun doSomething(){
    	print("I'm real")
    }
}

open class ProxyService(
    private val mService: MainService?
):Service{

    override fun doSomething(){
    	if(mService == null)
        	mService = MainService()
    	mService.doSomething()
    }
}

Main(){
    ProxyService().doSomething()
}

 

예제

유튜브의 경우 영상을 리스팅할 때 먼저 썸네일 이미지를 보여주고 썸네일 이미지 위로 마우스를 올릴 시에 프리뷰 영상을 보여준다. 썸네일 이미지를 보여주는 일은 가벼운 일이고 프리뷰를 보여주는 일은 무거운 일이다. 이렇게 썸네일 이미지는 일종의 placeholder의 역할이다.

 

썸네일을 보여주는 프록시 제공

interface Thumbnail{
    fun showImage()
    fun showPreview()
}

open class ProxyThumbnail(
    private val title: String,
    private val movieUrl: String,
    private val realThumbnail: RealThumbnail?
) : Thumbnail{

    override fun showImage(){
    	print("이미지 노출")
    }
    
    override fun showPreview(){
    	if (realThumbnail==null)
        	realThumbnail = RealThumbnail(title,movieUrl)
    	realThumbnail.showPreview()
    } 
    
}

위에서 프록시 썸네일은 이미지를 노출할 수 있지만 동영상은 직접 로드하지 않는다. 따라서, 매우 가벼우며 실제 영상을 보여줘야 할 때에는 RealThumbnail이 직접 수행하게 된다.

 

RealThumbnail 구현

open class RealThumbnail(
    private val title: String,
    private val movieUrl: String
) : Thumbnail{

    init{
    	//무거운 네트워킹 작업
    	print("영상 데이터 로딩")
    }
	override fun showImage(){
    	print("이미지 노출")
    }
    
    override fun showPreview(){
    	print("프리뷰 재생")
    } 
    
}

 

실제 사용 코드

val list = ArrayList<Thumbnail>()

list.add(ProxyThumbnail("movie1","/movie1.jpg");
list.add(ProxyThumbnail("movie2","/movie2.jpg");
list.add(ProxyThumbnail("movie3","/movie3.jpg");

//실제 사용 시점부터 메인 객체가 직접 수행함
//이 과정에서 메인 객체가 없을 경우 메인 객체가 생성됨.
list[0].showPreview() 

위처럼 필요할 때에만 실제 객체가 생성되기 때문에 매우 효율적이다.

 

 

참고

  • 얄팍한 코딩사전(객체지향 디자인패턴 1)