이 글은 아래 두 글로 부터 이어집니다.
한 번에 글을 보고 싶으신 분은 아래를 참고해주세요.
차이점
이 글을 정리하게 된 계기는 데코레이터 패턴과 프록시 패턴의 유사성에 있다.
실제로 둘은 원본 객체를 건드리지 않고 추가 기능을 실행할 수 있다는 점에서 유사하기에 자칫하면 헷갈릴 수 있다.
특히 Spring AOP의 경우는 프록시 패턴을 사용하였지만, 부가적인 처리를 한다는 점에서 데코레이터 패턴으로 설명하는 글들을 종종 볼 수 있었다.
그렇기에 제대로 이해하는 것이 좋을 것 같아 차이점에 대해서 정리해보려고 한다.
기준 | 데코레이터 패턴 | 프록시 패턴 |
---|---|---|
목적 | 객체에 동적으로 새로운 기능을 추가하기 위함 | 다른 객체에 대한 접근을 제어하거나 부가기능을 제공하기 위함 |
사용 시점 | 실행 시간에 객체의 기능을 확장하고자 할 때 | 객체의 생성이나 접근에 대한 제어가 필요할 때 |
구현 방식 | 추상 클래스나 인터페이스를 사용하여 객체에 새로운 기능을 추가 | 프록시 객체를 통해 실제 객체에 접근, 프록시 객체와 실제 객체는 같은 인터페이스를 구현 |
위와 같이 데코레이터 패턴과 프록시 패턴의 주요 차이점은 목적에 있다.
데코레이터 패턴은 동적으로 기능을 추가함에 의의를 두고 있기에 아래 정리할 활용사례에서도 클라이언트에 의해 제어되는 경우가 많다.
하지만 프록시 패턴은 접근을 제어하는 것에 의의를 두고 있기에 내부 동작에 의해 제어되는 경우가 많다.
적용 시 고려사항과 활용사례
데코레이터 패턴
그렇다면 데코레이터 패턴은 언제 사용해야할까?
- 데코레이터 패턴은 객체들을 사용하는 코드를 훼손하지 않으면서 런타임에 추가 행동들을 객체들에 할당할 수 있어야 할 때 사용해야 한다.
- 상속을 사용하여 객체의 행동을 확장하는 것이 어색하거나 불가능할 때 사용할 수 있다.
- 만일
final
키워드가 기입된 클래스의 경우는 데코레이터 패턴을 통해 래핑하여 재사용할 수 있다.
- 만일
예를 들어 아래와 같은 부분들에 사용되었다.
텍스트 편집기
- 텍스트 편집기에서 굵게, 이탤릭체, 밑줄 등과 같은 다양한 텍스트 포맷 옵션을 지원한다.
Spring
- HttpServletRequestWrapper / HttpServletResponseWrapper
- Servlet에서 제공하는 Wrapper로 데코레이터 패턴을 이용한다.
- HttpServletRequest와 HttpServletResponse을 확장하여 기능을 추가할 수 있다.
- ServerHttpRequestDecorator / ServerHttpResponseDecorator
- Webflux에서 사용되는 HTTP 요청 / 응답 데코레이터이다.
- ServerHttpRequest와 ServerHttpResponse를 커스터마이징 할 때 사용된다.
프록시 패턴
그러면 프록시 패턴은 언제 사용해야 할까?
- 가상 프록시, 지연 로딩이 필요한 경우
- 부담되는 서비스 객체를 바로 초기화 한다면 리소스 낭비가 발생 할 수 있으므로 프록시 객체를 통해 객체 초기화를 할 수 있다.
- 보호 프록시, 접근 제어가 필요한 경우
- 특정 클라이언트에 대해서만 서비스 객체를 이용할 수 있도록 하려는 경우 프록시 객체를 통해서 처리할 수 있다.
- 원격 프록시, 원격 서비스의 로컬 실행이 필요한 경우
- 서비스 객체가 원격 서버에 있는 경우에 네트워크를 통해 클라이언트의 요청을 전달하여 처리할 수 있다.
- 로깅 프록시, 서비스 객체에 대한 로깅이 필요한 경우
- 프록시 객체에서 서비스에 전달하기 전과 후로 로깅을 진행할 수 있다.
- 캐싱 프록시, 요청 결과를 캐시하고 생명주기를 관리해야하는 경우
- 프록시 객체를 통해서 항상 같은 결과를 생성하는 반복 요청에 대한 캐싱을 구현하여 처리할 수 있다.
예를 들어 아래와 같은 부분에 사용되었다.
Spring
- Spring JPA
- JPA 의 지연 로딩의 경우도 가상 프록시를 적용하여 실제로 객체를 조회하기 이전까지 프록시 객체로
Entity
를 대신하여 제공한다.
- JPA 의 지연 로딩의 경우도 가상 프록시를 적용하여 실제로 객체를 조회하기 이전까지 프록시 객체로
- Spring AOP
- Spring AOP는 프록시 패턴을 사용하여 트랜잭션 관리, 로깅, 보안 등의 작업을 프록시에서 처리한다.
간단 정리
데코레이터 패턴과 프록시 패턴 모두 기존 객체를 수정하지 않고 추가 기능을 실행시키는 데 사용된다.
하지만 데코레이터 패턴은 실행 시간에 객체의 기능을 동적으로 확장하고, 프록시 패턴은 객체의 생성이나 접근을 제어하기 때문에 목적과 사용 방법에 차이가 있다.
참고
https://inpa.tistory.com/entry/GOF-💠-데코레이터Decorator-패턴-제대로-배워보자