프록시 패턴이란?

프록시 패턴은 대상 객체에 접근하기 전 그 접근에 대한 흐름을

가로채 대상 객체 앞단의 인터페이스 역할을 하는 디자인 패턴이다

 

이를 통해 객체의 속성, 변환 등을 보완하며 보안, 데이터 검증, 캐싱, 로깅에 사용한다

 

다르게 설명해 보자면

 

Proxy는 우리말로 대리자, 대변인 이라는 뜻이다

대리자, 대변인은 다른 누군가를 대신해서 그 역할을 수행하는 존재이다

프로그램에서 봤을 때도 똑같다 프록시에게 어떤 일을 대신 시키는 것이다

 

구체적으로 인터페이스를 사용하고 실행시킬 클래스에 대한 객체가 들어갈 자리에

대리자 객체를 대신 투입해 클라이언트 쪽에서 실제  실행시킬 클래스에대한 객체를 통해

메서드를 호출하고 반환 값을 받는지, 대리자 객체를 통해 메서드를 호출하고 반환 값을 받는지

전혀 모르게 처리하는 것이다

 

일종의 프록시는 비서역할을 하는 것이다

중요한 것은 흐름제어만할 뿐 결과값을 조작하거나 변경시키면 안된다

비서에게 물건을 전달해달라 했는데 비서가 그 물건을 바꾸거나 훼손하면 안되는거 처럼 말이다

 

정리하자면

- 대리자는 실제 서비스와 같은 이름의 메서드를 구현한다 이때 인터페이스를 사용한다

- 대리자는 실제 서비스에 대한 참조 변수를 갖는다(합성)

- 대리자는 실제 서비스의 같은 이름을 가진 메서드를 호출하고 그 값을 클라이언트에게 돌려준다

- 대리자는 실제 서비스의 메서드 호출 전후에도 별도의 로직을 수행할 수도 있다

 

프록시 패턴의 종류

가상프록시

꼭 필요로 하는 시점까지 객체의 생성을 연기하고

해당 객체가 생성된 것 처럼 동작하도록 만들고 싶을 때 사용하는 패턴이다

프록시 클래스에서 작은 단위의 작업을 처리하고 리소스가 많이 요구되는 작업들이 필요할 경우만

주체 클래스를 사용하도록 구현한다

ex: Google Docs

 

원격프록시

원격 객체에 대한 접근을 제어 로컬 환경에 존재하며,

원격 객체에 대한 대변자 역할을 하는 객체 서로 다른 주소 공간에 있는 객체에 대해 마치 같은 주소 공간에 있는 것 처럼 동작하게 하는 패턴이다

ex: Google Docs

 

보호프록시

주체 클래스에 대한 접근을 제어하기 위한 경우에 객체에 대한 접근 권한을 제어하거나

객체마다 접근 권한을 달리하고 싶을 경우 사용하는 패턴으로

프록시 클래스에서 클라이언트가 주체 클래스에 대한 접근을 허용할지 말지 결정하도록 할 수 있다

ex: spring security

 

예시로 알아보기

Image 클래스

public interface Image {
    public void displayImage();
}

 

Real_Image 클래스

public class Real_Image implements Image {
	private String fileName;
    
    public Real_Image(String fileName) {
    	this.fileName = fileName;
    }
    
    private void loadFromDisk(String fileName) {
    	System.out.println("로딩: " + fileName);
    }
    
    @Override
    public void displayImage() {
        System.out.println("보여주기: " + fileName);
    }
}

 

Proxy_Image 클래스

public class Proxy_Image implements Image {
    private String fileName;
    private Real_Image realImage;
    
    public Proxy_Image(String fileName) {
    	this.fileName = fileName;
    }
    
    @Override
    public void displayImage() {
    	if (realImage == null) {
        	realImage = new Real_Image(fileName);
        }
        realImage.displayImage();
    }
}

 

Proxy_Pattern 클래스 (메인)

public class Proxy_Pattern {
    public static void main(String args[]) {
        Image image1 = new Proxy_Image("test1.jpg);
        Image image2 = new Proxy_Image("test2.jpg);
        
        image1.displayImage();
        image2.displayImage();
    }
}

 

이처럼 메인 클래스에서 Real_Image 클래스에 직접 접근하지 않고

Proxy_Image 클래스에서 객체를 생성하여 대신 일을 수행하는걸 확인 할 수 있다

 

흐름제어가 필요한 이유

게임을 예로들면 배틀그라운드를 한다고 생각해보자

게임을 시작하기전에 유저들이 모이고 카운트다운이 흐른다

카운트가 끝나야 비행기를 타고 게임에 입장하게 되는데

이건 데이터가 큰 이미지나 그래픽을 로딩하는데 시간이 걸리기 때문에

카운트를 세면서 기다리는것이라고 생각하면된다

이때 가만히 멈춘 화면을 보고 있으면 사람들은 지루해 할 것이다

그래서 상대적으로 작은 데이터(대기화면장소)가 먼저 로딩이 끝나면

우선적으로 사람들에게 보여주고 캐릭터를 움직일 수 있게 해준것이다

'CS' 카테고리의 다른 글

[CS] 노출모듈 패턴  (0) 2022.10.20
[CS] 이터레이터 패턴  (0) 2022.10.20
[CS] 웹 (WEB)과 웹 어플리케이션 서버 (WAS)  (0) 2022.10.18
[CS] 클라이언트(Client)와 서버(Server)  (0) 2022.10.18
[CS] 전략 패턴  (0) 2022.10.17