프록시 패턴
proxy : 대리인
특정 객체에 대한 접근을 제어하거나 기능을 추가할 수 있는 패턴. 즉 특정 객체에 접근하기 전에 프록시 객체를 먼저 지나서 접근하게 된다.
-> 초기화 지연, 접근 제어, 로깅, 캐싱 등 다양하게 응용하여 사용할 수 있다.
코드로 알아보기
아래와 같은 Client가 GameService의 코드는 바꾸지 않고 startGame이 실행되고 종료되기까지 얼마나 시간이 걸리는지 알고 싶다면?
GameService
프록시 패턴을 적용하지 않는다면 Client코드의 main시작 부분과 startGame마지막 부분에 시간을 재면 될 것이다. 하지만 프록시 패턴을 적용하면 이렇게 하지 않아도 된다.
먼저 GameService를 전혀 건드리지 않고 측정하는 방법을 보자. (GameService에 Thread.sleep()을 사용하여 수행시간을 고의적으로 지연 시켰다.)
GameService
단순하게 GameService를 상속하는 프록시 클래스를 만들면 된다.
GameServiceProxy
그리고 startGame을 오버라이드하여 super.startGame()의 위 아래에 시간 측정 코드를 삽입하였다.
그리고 Client는 프록시를 사용하면 되는 것이다.
실행결과:
위에서 적용한 방법은 기존코드를 전혀 변경하지 않고 프록시 패턴을 적용하는 방법이었다.
이번에는 맨 위에서 본 프록시 패턴 클래스 다이어그램에서 본 방법으로 적용해보자.
Client코드를 먼저 보면 프록시 안에 사용할 Service객체를 넣어주는 것을 볼 수 있다.
DefaultGameService는 코드를 더 유연하게 하기 위해 GameService 인터페이스를 정의하고 그것을 구현했다.
이제 프록시 객체를 보자. 프록시는 이전에 데코레이터 패턴에서 본 것처럼 GameService를 가지고 있고, 역시 GameService를 구현한다.
프록시의 startGame을 보면 수행시간을 측정하는 데 필요한 로직과 Client에서 받은 GameService타입 객체의 startGame메소드를 super를 사용하여 실행시키는 것을 볼 수 있다.
이렇게 하면 시간 측정 외에도 다양한 로직을 삽입하여 GameService를 교체할 수도 있다. 만약 아래와 같이 한다면 Client에서 GameService를 정하지 않고, 프록시 객체 내에서 GameService를 결정하게 된다.
(Lazy Initialization이 적용된 프록시 객체)
프록시 객체만을 사용하는 Client:
장점과 단점
장점
1. 기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있다. (OCP)
2. 기존 코드가 해야 하는 일만 유지할 수 있다. (SRP)
3. 기능 추가 및 초기화 지연등으로 다양하게 활용할 수 있다.
단점
코드의 복잡도가 증가한다.
실제로 어디에 사용되나?
자바 : 다이나믹 프록시, java.lang.reflect.Proxy
스프링 : 스프링 AOP
출처: 인프런 백기선님 '코딩으로 학습하는 GoF 강의'
https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4
'Design Pattern' 카테고리의 다른 글
14. 커맨드 패턴( Command pattern) (0) | 2021.12.24 |
---|---|
13. 책임 연쇄 패턴 (chain - of - responsibility) (0) | 2021.12.23 |
11. 플라이웨이트 패턴 (flyweight pattern) (0) | 2021.12.22 |
10. 퍼사드 패턴 (facade pattern) (0) | 2021.12.21 |
9. 데코레이터 패턴(Decorator pattern) (0) | 2021.12.21 |