TextViewer
class와 큰 영상을 다루는 VideoViewer
class가 있다고 가정해 보자.TextViewer
와 VideoViewer
객체를 만들고, 내부에 정의되어 있는 멤버 메서드와 필드들을 모두 활용하며 코드를 작성할 것이다.TextViewer
는 빠른 시간 내에 로드될 수 있지만, VideoViewer
는 오랜 시간이 소요될 것이다.VideoViewer
를 사용할 수도, 안할 수도 있는데 일단 오랜 시간을 기다려야만 한다.TextViewer
객체가 활용되면 그 시점에 실제 TextViewer
객체가 생성되어 역할을 수행하게 되고, VideoViewer
객체 또한 직접적으로 활용되는 시점에 생성된다.프록시 패턴을 적용하지 않으면 Client의 요청이 그대로 DB에 전해지게 된다.
소수의 Client의 경우 상관없지만, 트래픽이 증가할 수록 많은 양의 리소스를 처리해야 하기 때문에 DB와 소통하는 쿼리가 느려질 것이다.
본 상황을 해결하려면 Client 요청에 따라 쿼리를 DB로 전달하는 모든 클래스(**Dao)마다 흐름을 제어하기 위한 코드를 추가해야 한다.
또한, Dao class는 DB와의 소통에 대한 역할만 수행해야 하는데, 흐름 제어 역할도 가져버리면 객체 지향 5대 원칙 중 ‘단일 책임의 원칙(SRP)’에 위반된다.
→ 코드 중복 야기! + 하나의 클래스가 여러 책임을 갖게 됨! + 비효율적!
따라서 중간에 프록시 객체를 넣어두면, 프록시 객체가 흐름을 제어하는 역할을 수행할 수 있다.
위 사진은 다음과 같이 동작한다.
Client
는 Subject
interface 타입의 객체를 활용하려 한다.
Subject
interface의 구현체로 RealSubject
class가 있다.이때, 일반적으로는 RealSubject
class 객체를 생성하여 활용한다.
Subject subject = new RealSubject();
하지만 프록시 패턴을 적용할 경우, 다음과 같이 Proxy
class를 활용하게 된다.
Subject subject = new Proxy();
여기서 Proxy
class는 다음과 같이 정의된다.
public class Proxy implements Subject {
Subject realSubject;
@Override
public void doAction() {
if (realSubject == null) {
realSubject = new RealSubject();
}
realSubject.doAction();
}
}
*JPA의 지연 로딩과 프록시 객체 활용