A객체가 B객체로 직접 요청을하는것이 아닌 어떠한 대리자를 통해 간접적 요청하여 접근을 제어하는 패턴
손님이 식당에 토시살 3인분을 주문했는데 식당에서 직접 횡성으로가서 한우를 잡아오지않고 냉장되어있던 토시살을 꺼내오는 느낌..
요청은 실제 객체를 호출하지않고 대리자인 Proxy에 요청해 값을 넘겨받는다.
또한 요청은 interface에 의존하므로 요청자는 의존하는것이 Proxy인지 실제객체인지 알 수 없음.
강의중 학습 테스트를 통해 더 이해하게됬다.


RealSubject는 실제 객체며 이 클래스의 역할은 호출시 로그를 출력하고 1초간 쓰레드를 잠시 멈춘다.
실 객체인 RealSubject는 Subject라는 인터페이스의 구현체이다.

요청을 하는 객체인 ProxyPatternClient는 Subject를 의존하며
주입받은 Subject의 operation() 이라는 메서드를 제공받아 사용한다.


테스트를 통해 프록시를 사용하지 않았을때의 경우를 확인해봤다.
요청이 실객체를 접근해 operation이라는 메서드를 실행하므로
execute()가 실행된 뒤 무조건 1초간 Thread가 멈추게 된다.
총 3초에 걸려 Client의 요청을 완료 할 수 있었다.
프록시 객체를 만들어 프록시를 이용해보자.

CacheProxy는 Subject를 구현한다.
CacheProxy또한 인터페이스를 의존하지만 구현클래스인 실객체를 주입받을 수 있다.
구현한 Subject를 필드 변수로 저장하며 이러한 필드를 target이라 한다.
이름에서부터 알 수 있다시피 캐싱을 진행하기위해 캐시값을 저장한 cacheValue 필드가 존재한다.
인터페이스 구현 메서드를 훑어보자
로그로 프록시 호출을 남기고
cacheValue 값이 null이라면 캐싱할 값이 없기때문에 실제 객체를 불러와 operation()을 진행한뒤 cacheValue 필드에 실 객체 반환값을 저장한다.
캐시값이 존재한다면 실 객체를 호출하지않고 캐시된 값을 반환한다.
테스트를 진행해보자.


우선 실 객체를 생성한뒤 프록시 객체에 주입해준다.
요청객체는 전 테스트와 달리 실객체가아닌 프록시객체를 주입받는다.
테스트를 전과 동일하게 진행하면 아래와같은 로그를 확인 할 수 있고 전과 달리 1초만에 모든 요청이 완료되는것을 확인 할 수 있다.
처음 클라이언트의 execute(); 실행시
Subject를 구현한 프록시를 주입받았으므로 프록시의 Operation()이 실행된다.
최초 메서드 실행에 프록시 호출 이란 첫번째 로그가 찍히고
현재 프록시 객체의 cacheValue에는 아무값도 저장되지않았으므로 실 객체를 호출한다.
두번째 execute() 실행시 프록시객체는 cacheValue에는 저장된 값이 존재하므로 실 객체를 호출하지 않고 캐시된 값을 호출한다.
세번째 execuete()의 경우도 마찬가지다.
이렇게 프록시 객체를 활용하면 요청자의 요청 접근을 제어하여 제한하거나 더 빠르게 요청을 완료 할 수 있게된다.

'공부 > Java' 카테고리의 다른 글
Decorator Pattern (0) | 2024.01.09 |
---|---|
TemplateMethod Pattern | Strategy Pattern (0) | 2024.01.06 |
동시성 문제와 TreadLocal (0) | 2024.01.04 |