2023.08.13

프록시 패턴

프록시 패턴이란, 기존 객체를 대신하여 처리하는 것으로 로직의 흐름을 제어하는 패턴이다. 프록시 라는 말 자체가 대리 와 같은데, 실제 클라이언트가 기능을 호출하는 것이 아니라 프록시를 거쳐서 사용하는 것과 같다. 단 제어만 할뿐 조작이나 변경을 하는 것이 아니다. 이런, 굳이 프록시를 두는 이유는… 다음과 같다.


필요성

  1. 보안
  2. 캐싱
  3. 유효성 검사
  4. 로깅
  5. 동시성, 지연 초기화

등등


단점

프록시를 사용하기 위해 클래스를 추가해야하기 때문에 복잡도가 증가한다. 또한, 프록시를 통해서 작동하기 때문에 속도가 느려질 수 있다.


장점

기존 객체의 로직을 수정할 수 없거나 접근을 제어하는 역할로 사용할 수 있다. 기존 로직에 영향을 주지 않고 새로운 기능을 동작하도록 할 수 있어 확장성이 좋다. 개방 폐쇠 원칙, 단일 책임 원칙에도 충족하기 때문에 객체 지향적으로 사용할 수 있다.


종류

이런 프록시 패턴을 생각보다 많이 사용되는데, 목적에 따라서 패턴 종류도 다양하다. 간단히 기본, 가상 프록시만 확인하자. 우선 예시로 기존 Subject가 있다고 생각하자.

interface Subject {
	void activate();
}

class ASubject implements Subject {
	public void activate() {
		System.out.println("뭔가 일어난다!");
	}
}


기본 프록시

기본 프록시의 경우 위와 같이 Proxy 객체에서 해당 Subject 를 지정하고, 이를 수행함과 동시에 우리가 원하는 기능 (여기선 “기존 기능 대신 무언가 추가된다.”)를 작동하도록 할 수 있다.

class Proxy implements Subject {
	private ASubject subject;

	Proxy(ASubject subject) {
		this.subject = subject;
	}

	public void activate() {
		subject.activate();

		System.out.println("기존 기능 대신 무언가 추가된다.");
	}
}

class Client {
	public static void main(String[] args) {
		ASubject subject = new Proxy(new ASubject());

		subject.activate();
	}
}


가상 프록시

가상 프록시의 경우 지연 초기화 방식이라는 것을 생각해야한다. 지연 초기화가 필요한 이유는 원래 대로라면 서비스가 시작될 때 객체가 초기화되는데, 특정 시점에 초기화를 해야하는 경우가 있을 수 있다. 또는, 해당 객체가 너무 무거워서 서비스 로드 속도를 개선 시키기 위해 가상 프록시를 사용한다.

class Proxy implements Subject {
	private ASubject subject;

	Proxy() {}

	public void activate() {
		if(subject == null) {
			subject = new ASubject();
		}
		subject.activate();

		System.out.println("기존 기능 대신 무언가 추가된다.");
	}
}

class Client {
	public static void main(String[] args) {
		ASubject subject = new Proxy(new ASubject());

		subject.activate();
	}
}

위와 같이 작성하면, activate 가 호출될 때 객체가 생성된다. 이 외에도 보호, 로깅, 캐싱, 원격 프록시 등등이 있다.



Leave a comment