이 포스팅은 인프런 : 스프링 핵심 원리 - 고급편 을 참고하여 작성되었습니다.
(실습이 많은 챕터라서 강의의 많은 부분이 생략되었다.)
이전에 학습했던 패턴으로 로그추적기를 도입하려면 원본 코드를 수정해야 한다.
원본 코드를 수정하지 않고 로그추적기를 도입하려면 프록시의 개념을 이해해야 한다.
프록시를 사용하여 접근 제어, 캐싱, 부가기능 추가 등이 가능하다.
객체에서 프록시가 되려면 클라이언트는 서버에게 요청을 한 것인지, 프록시에게 요청을 한 것인지 조차 몰라야 한다! -> 서버와 프록시는 같은 인터페이스를 사용해야 한다. 그리고 클라이언트가 사용하는 서버 객체를 프록시 객체로 변경해도 클라이언트 코드를 변경하지 않고 동작할 수 있어야 한다.
GOF 디자인 패턴
둘 다 프록시를 사용하는 방법이지만 GOF 디자인 패턴에서는 이 둘을 의도에 따라 프로시 패턴과 데코레이터 패턴으로 구분한다.
- 프록시 패턴 : 접근 제어가 목적
- 데코레이터 패턴 : 새로운 기능 추가가 목적
Decorator 기능에 일부 중복이 있다. 꾸며주는 역할을 하는 Decorator들은 스스로 존재할 수 없다. 따라서 내부 호출 대상인 component를 가지고 있어야 한다. 그리고 component를 항상 호출해야 한다. 이 부분이 중복이다.
이런 중복을 제가하기 위해 component를 속성으로 가지고 있는 Decorator라는 추상 클래스를 만드는 방법도 고민 할 수 있다. 이렇게 하면 추가로 클래스 다이어그램에서 어떤 것이 실제 컴포넌트인지, 데코레이터인지 명확하게 구분할 수 있다.
프록시를 사용하여 원본 코드를 변경하지 않고, 로그 기능을 추가 할 수 있었다.
이론적으로는 모든 객체에 인터페이스를 도입해서 역할과 구현을 나누는 것이 좋다. 이렇게 하면 역할과 구현을 나누어서 구현체를 매우 편리하게 변경할 수 있다. 하지만 실제로는 구현을 거의 변경할 일이 없는 클래스도 많다.
인터페이스를 도입하는 것은 구현을 변경할 가능성이 있을 때 효과적인데, 구현을 변경할 가능성이 거의 없는 코드에 무작정 인터페이스를 사용하는 것은 실용적이지 않다!
-> 이렇게 프록시를 사용해 부가기능을 적용할 수 있었는데, 프록시 클래스를 많이 만들어야 한다는 단점이 있었다.