[review]프록시 패턴과 데코레이터 패턴

corncheese·2023년 11월 5일
0

이 포스팅은 인프런 : 스프링 핵심 원리 - 고급편 을 참고하여 작성되었습니다.
(실습이 많은 챕터라서 강의의 많은 부분이 생략되었다.)

이전에 학습했던 패턴으로 로그추적기를 도입하려면 원본 코드를 수정해야 한다.
원본 코드를 수정하지 않고 로그추적기를 도입하려면 프록시의 개념을 이해해야 한다.

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

프록시란? 클라이언트가 요청한 결과를 서버에 직접 요청하는 것이 아닌, 간접적으로 서버에 요청할 수 있도록 하는 대리자.

프록시를 사용하여 접근 제어, 캐싱, 부가기능 추가 등이 가능하다.

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

프록시의 주요 기능

  • 접근제어 (권한에 따른 접근 차단, 캐싱, 지연 로딩)
  • 부가 기능 추가(요청 값이나 응답 값을 중간에 변형, 실행시간을 측정하여 로를 남긴다)

GOF 디자인 패턴
둘 다 프록시를 사용하는 방법이지만 GOF 디자인 패턴에서는 이 둘을 의도에 따라 프로시 패턴과 데코레이터 패턴으로 구분한다.

  • 프록시 패턴 : 접근 제어가 목적
  • 데코레이터 패턴 : 새로운 기능 추가가 목적


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

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

  • 의도
    프록시 패턴과 데코레이터 패던은 그 모양이 거의 같고, 상황에 따라 똑같을 때도 있다. 이 둘을 어떻게 구문해야 하는것일까?
    디자인 패턴에서 중요한 것은 해당 패턴의 겉모양이 아닌 그 패턴의 의도가 더 중요하다. 따라서 의도에 따라 패턴을 구분한다.
    프록시 패턴의 의도 : 다른 개체에 대한 접근을 제어하기 위해 대리자를 제공
    데코레이터 패턴의 의도 : 객체에 추가 책임(기능)을 동적으로 추가하고, 기능 확장을 위한 유연한 대안 제공

인터페이스 기반 프록시와 클래스 기반 프록시

프록시를 사용하여 원본 코드를 변경하지 않고, 로그 기능을 추가 할 수 있었다.

  • 인터페이스가 없어도 클래스 기반 프록시를 생성할 수 있다.
  • 클래스 기반 프록시는 해당 클래스에만 적용할 수 있다. 인터페이스 기반 프록시는 인터페이스만 같으면 모든 곳에 적용할 수 있다.
  • 클래스 기반 프록시는 상속을 하기 때문에 몇가지 제약이 있다.
    1. 부모 클래스의 생성자를 호출해야 한다.
    2. 클래스에 fianl 키워드가 붙으면 상속이 불가능하다.
    3. 메서드에 final 키워드가 붙으면 해당 메서드를 오버라이딩 할 수 없다.
  • 인터페이스 기반 프록시의 단점은 인터페이스가 필요하다는 것 자체이다.
  • 이론적으로는 모든 객체에 인터페이스를 도입해서 역할과 구현을 나누는 것이 좋다. 이렇게 하면 역할과 구현을 나누어서 구현체를 매우 편리하게 변경할 수 있다. 하지만 실제로는 구현을 거의 변경할 일이 없는 클래스도 많다.
    인터페이스를 도입하는 것은 구현을 변경할 가능성이 있을 때 효과적인데, 구현을 변경할 가능성이 거의 없는 코드에 무작정 인터페이스를 사용하는 것은 실용적이지 않다!

    -> 이렇게 프록시를 사용해 부가기능을 적용할 수 있었는데, 프록시 클래스를 많이 만들어야 한다는 단점이 있었다.

0개의 댓글