디자인 패턴 : 프록시 패턴

DanChu 🌟·2022년 7월 30일
0

프록시 = 대리자, 대변인

어떤 객체를 사용하고자 할 때, 객체를 직접적으로 참조하지 않고, 해당 객체를 대항하는 객체를 통해 대상 객체에 접근하는 방식을 사용 -> 해당 객체가 메모리에 존재하지 않아도 기본적인 정보를 참조 혹은 설정할 수 있음, 실제 객체의 기능이 필요한 시점까지 객체 생성 미루기 가능


프록시 패턴의 예시

텍스트와 이미지가 같이 로딩되어야하는 페이지

  • 텍스트는 용량이 작지만 이미지는 큰 용량 때문에 로딩 시간이 더 걸림
  • 모두 로딩이 완료된 후 화면에 뿌리지 않고, 먼저 로딩이 끝난 부분부터 화면에 뿌리도록 처리
    - 텍스트 처리용 프로세스, 이미지 처리용 프로세스 별도 운영 필요
// Image.java (interface)

public interface Image {
    public void displayImage();
}
// Real_Image.java

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

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_Main.java

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();
        System.out.println();
        image2.displayImage();
    }
}

결과

로딩: test1.png
보여주기: test1.png

로딩: test2.png
보여주기: test2.png
  • Proxy_Main에서 Real_Image 클래스에 직접 접근하지 않고,
    Proxy_Image 클래스에서 객체 생성하여 대신 일 수행함
  • Proxy는 displayImage() 메서드를 호출하고 그 반환값을 Main에 반환

프록시 패턴의 장단점

장점

  • 사이즈 큰 객체가 로딩되기 이전에도 프록시를 통해 참조가 가능
  • 실제 객체의 public, protected 메소드를 숨기고 인터페이스를 통해 노출 시킬 수 있음
  • 로컬에 있지 않고 떨어져있는 객체를 사용할 수 있음
  • 원래 객체에 접근에 대해 사전처리가 가능

단점

  • 객체 생성할 때 한 단계를 거치기때문에 빈번한 객체 생성이 필요한 경우에 성능 저하될 수 있음
  • 프록시 내부에서 객체 생성위한 스레드가 생성, 동기화가 구현되어야하는 경우 성능 저하 가능
  • 로직이 복잡해져 가독성이 떨어질 수 있음

포워드 프록시 vs. 리버스 프록시 (프론트엔드와 백엔드)

포워드 프록시 (프론트엔드)

  • 클라이언트가 인터넷에 직접 접근하지 않고, 포워드 프록시 서버가 요청을 받고 인터넷에 연결하여 결과를 클라이언트에게 전달 (forward)

리버스 프록시 (백엔드)

  • 클라이언트가 인터넷에 데이터 요청하면 리버스 프록시가 이 요청을 받아 내부 서버에서 데이터를 받은 후 클라이언트에 전달
  • 클라이언트는 내부 서버에 대한 정보를 알 필요 없이 리버스 프록스에만 요청하면 됨
  • 내부 서버(WAS)에 직접적으로 접근한다면 DB에 접근이 가능하기 때문에 중간에 리버스프록시를 두고 클라이언트와 내부 서버 사이의 통신을 담당
  • 내부 서버에 대한 설정으로 로드 밸런싱(Load Balancing)이나 서버 확장 등에 유리





references

0개의 댓글