14. 프록시 패턴

AlmondGood·2022년 7월 29일
0

디자인패턴

목록 보기
15/16
post-thumbnail

프록시 패턴(Proxy Pattern)

프록시 패턴이란, 특정 객체로의 접근을 제어하는 대리인을 사용하는 패턴입니다.

우리가 친구에게 전화를 걸 때, 휴대폰과 휴대폰끼리 직접 연결되지 않습니다.
휴대폰의 전파가 기지국에 연결된 뒤, 기지국대상 휴대폰으로 전파를 보냅니다.

여기서 기지국이 프록시의 역할을 합니다.



프록시 패턴 구현

전화 걸기 인터페이스입니다.

interface Call {
    String connect();
}

connect() 메소드를 통해 사용자 -> 기지국, 기지국 -> 대상 으로 연결됩니다.


전화를 받을 대상 클래스입니다.

class Person implements Call{
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String connect() {
        return name + " : 여보세요";
    }
}

기지국 클래스입니다.

// 프록시
class Station implements Call {
    Person person;

    public Station(Person person) {
        this.person = person;
    }

    public void callPerson(Person person) {
        this.person = person;
    }

    @Override
    public String connect() {
        return person.connect();
    }
}

생성자 또는 callPerson() 메소드로 전화 걸 사람을 지정하고,
connect() 로 연결합니다.


메인 함수입니다.
전화를 거는 사람, 사용자에 해당합니다.

public static void main(String[] args) {

	// 전화를 받을 사람 객체 생성
	Person FeH2O = new Person("철수");
    Person youngHee = new Person("영희");

	// 기지국 객체 생성 (대상 : 철수)
	Station station = new Station(FeH2O);

	System.out.println(station.connect());	// "철수 : 여보세요"

	// 대상 : 영희
	station.callPerson(youngHee);

	System.out.println(station.connect()); // "영희 : 여보세요"
}

station.connect() 메소드로 기지국과 연결되어,
기지국은 person.connect() 로 전화를 받을 대상 객체의 메소드를 호출합니다.

대상으로부터 기지국이 응답을 받고, 그 응답을 다시 사용자로 넘겨주어
사용자가 응답(println())을 받게 됩니다.


이처럼 대상 객체와 사용자 사이에서 접근을 제어하는 것이 프록시입니다.

위의 예제에서는 객체끼리 직접 엮이는 것을 막아 의존도를 낮추고(DIP),
객체를 직접 수정하지 않고도 확장을 용이하게 만드는 역할을 했죠(OCP).

하지만 프록시는 이러한 역할만 할 수 있는 것은 아닙니다.




# 전체 코드

interface Call {
    String connect();
}

class Person implements Call{
    String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public String connect() {
        return name + " : 여보세요";
    }
}

// 프록시
class Station implements Call {
    Person person;

    public Station(Person person) {
        this.person = person;
    }

    public void callPerson(Person person) {
        this.person = person;
    }

    @Override
    public String connect() {
        return person.connect();
    }
}

public static void main(String[] args) {

	// 전화를 받을 사람 객체 생성
	Person FeH2O = new Person("철수");
    Person youngHee = new Person("영희");

	// 기지국 객체 생성 (대상 : 철수)
	Station station = new Station(FeH2O);

	System.out.println(station.connect());	// "철수 : 여보세요"

	// 대상 : 영희
	station.callPerson(youngHee);

	System.out.println(station.connect()); // "영희 : 여보세요"
}




프록시 패턴의 종류

원격 프록시(Remote Proxy)

  • 네트워크 환경에서 사용자와 서버의 중간자 역할을 합니다.
  • 한국에 있는 사용자로부터 명령을 받으면, 프록시 서버는 명령을 미국에 있는 서버로 보내고,
    그 명령의 결과값을 사용자로 다시 전달합니다.
  • 사용자와 서버가 직접 연결되지 않아 보안성이 향상됩니다.

가상 프록시(Virtual Proxy)

  • 데이터를 불러오는 데 오랜 시간이 걸릴 때 사용합니다.
  • 게임에서 다음 맵으로 넘어갈 때, 프록시는 로딩 화면을 보여주다가,
    로딩이 완료되면 다음 맵을 보여줍니다.

보호 프록시(Protection Proxy)

  • 권한에 따라 접근을 제어하고 싶을 때 사용합니다.
  • 게시글 작성자가 아닌 사람이 글을 수정하려고 할 때, 이를 제어합니다.




프록시 패턴의 장단점

장점

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

단점

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

https://velog.io/@newtownboy/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%ED%94%84%EB%A1%9D%EC%8B%9C%ED%8C%A8%ED%84%B4Proxy-Pattern

포워드 프록시 vs 리버스 프록시

포워드 프록시

사용자가 서버로 리소스를 요청할 때 프록시 서버를 거쳐서 요청합니다.

  • 서버는 사용자가 아닌 프록시의 IP를 받기 때문에 사용자가 누군지 모릅니다.
    즉, 서버에게 클라이언트가 누구인지 감추는 역할을 합니다.
  • 또는 특정 사이트의 접근을 제한할 수도 있습니다.
  • 위의 특징 때문에 기업 사내망에서 주로 사용됩니다.
  • 캐시를 사용하여 동일한 요청이 들어오면, 결과를 캐시에서 불러오기 때문에 성능이 향상됩니다.

리버스 프록시

사용자가 서버로 리소스를 요청하면, 결과값이 프록시 서버를 거쳐 사용자에 도달합니다.

  • 사용자는 프록시의 IP를 받기 때문에 서버의 정보를 모릅니다.
  • 사용자는 서버의 정보를 모르기 때문에 보안성이 향상됩니다.




참고 자료

https://sujinhope.github.io/2021/06/13/Network-%ED%94%84%EB%A1%9D%EC%8B%9C(Proxy)%EB%9E%80,-Forward-Proxy%EC%99%80-Reverse-Proxy.html

https://cornswrold.tistory.com/404

https://velog.io/@newtownboy/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%ED%94%84%EB%A1%9D%EC%8B%9C%ED%8C%A8%ED%84%B4Proxy-Pattern

profile
Zero-Base to Solid-Base

0개의 댓글