본문 바로가기
혼자 공부하는 것들/Spring

프록시 패턴과 데코레이터 패턴

by applepick 2022. 5. 10.
반응형

인프런 스프링 고급 원리를 들으면서 프록시 패턴과 데코레이터 패턴을 공부하고 있습니다. "둘이 뭔가 비슷한데?  뭐가 다른거지? 정확하게 어떠한 상황에서 사용해야 할까?"라고 느껴 정리를 해보려고 합니다.

프록시 패턴을 간단하게 말하자면 프록시는 다른 어떤 것과 이어지는 인터페이스의 역할을 하는 객체입니다. 

객체에서 프록시가 되려면, 클라이언트는 서버에게 요청을 한 것인지, 프록시에게 요청을 한 것인지 조차 몰라야 합니다. 쉽게 이야기해서 서버와 프록시는 같은 인터페이스를 사용해야 합니다. 그리고 클라이언트가 사용하는 서버 객체를 프록시 객체로 변경해도 클라이언트 코드를 변경하지 않고 동작할 수 있어야 합니다.

 

 

프록시 패턴에서 클래스 의존관계를 보면 클라이언트는 서버 인터페이스( ServerInterface )에만 의존하고 있습니다. 그리고 서버와 프록시가 같은 인터페이스를 사용합니다. 따라서 DI를 사용해서 대체 가능합니다.

 

이번에는 런타임 객체 의존 관계를 확인해보겠습니다. 런타임(애플리케이션 실행 시점)에 클라이언트 객체에 DI를 사용해서 Client -> Server에서 Client -> Proxy로 객체 의존관계를 변경해도 클라이언트 코드를 전혀 변경하지 않아도 됩니다. 클라이언트 입장에서는 변경 사실조차 모릅니다. DI를 사용하면 클라이언트 코드의 변경 없이 유연하게 프록시를 주입할 수 있습니다.

프록시의 주요 기능

접근 제어

  • 권한에 따른 접근 차단
  • 캐싱
  • 지연 로딩

부가 기능 추가

  • 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행합니다.
  • ex) 로그 남기기
  • ex) 요청 값에 부가 기능을 추가하여 반환

프록시 객체가 중간에 있으면 크게 접근 제어부가 기능 추가를 수행할 수 있습니다.

둘 다 프록시를 사용하는 방법이지만 GOF 디자인 패턴에서는 이 둘을 의도(intent)에 따라서 프록시 패턴과 데코레이터 패턴으로 구분합니다.(이 부분은 마지막에 설명드리겠습니다.)


프록시 패턴 -> 접근 제어가 목적

데코레이터 패턴 -> 새로운 기능 추가가 목적

 

여기서 생각해보면 데코레이터 패턴에서 일부 중복이 있습니다. 꾸며주는 역할을 하는 Decorator는 스스로 존재할 수 없습니다. 항상 꾸며줄 대상이 있어야 한다. 따라서 내부에 호출 대상인 component를 가지고 있어야 합니다. 그리고 component를 항상 호출해야 합니다. 이 부분이 중복됩니다. 이런 중복을 제거하기 위해 component를 속성으로 가지고 있는 Decorator라는 추상 클래스를 만드는 방법도 고민할 수 있습니다. 추상 클래스로 빼내면 클래스 다이어그램에서 어떤 것이 실제 컴포넌트 인지, 데코레이터인지 명확하게 구분할 수 있습니다. 

 

사실 프록시 패턴과 데코레이터 패턴은 그 모양이 거의 같고, 상황에 따라 정말 똑같을 때도 있습니다. 그러면 둘을 어떻게 구분하는 걸까요? 디자인 패턴에서 중요한 것은 해당 패턴의 겉모양이 아니라 그 패턴을 만든 의도가 더 중요합니다. 따라서 의도에 따라 패턴을 구분합니다.

 

프록시 패턴의 의도 -> 다른 개체에 대한 접근을 제어하기 위해 대리자를 제공

데코레이터 패턴의 의도 -> 객체에 추가 책임(기능)을 동적으로 추가하고, 기능 확장을 위한 유연한 대안 제공

 

프록시를 사용하고 해당 프록시가 접근 제어가 목적이라면 프록시 패턴, 새로운 기능을 추가하는 것이 목적이라면 데코레이터 패턴이 됩니다.

 

* 잘못된 부분이있다면 댓글로 알려주세요!

피드백해주시면 감사하겠습니다!

 

반응형

댓글