BoostStudy / design-patterns

디자인 패턴의 아름다움 스터디 저장소
6 stars 0 forks source link

CHAPTER 7 구조 디자인 패턴 - 1 #7

Closed lee-ji-hoon closed 6 months ago

lee-ji-hoon commented 7 months ago

프록시 패턴

실제 객체를 대신하는 객체가 흐름을 제어하여 실제 객체를 조작하는 패턴

interface RealObject {
    fun performOperation()
}
class RealObjectImpl : RealObject {
    override fun performOperation() {
        println("RealObject performing operation")
    }
}
class VirtualProxy : RealObject {
    private val realbject by lazy { RealObjectImpl() }
    override fun performOperation() {
        realObject.performOperation()
    }
}

Java 언어 외에 다른 프로그래밍 언어에서 동적 프록시를 어떻게 구현하는지에 대한 이야기가 나오는데 다른 언어 말고 retrofit에서의 Dynamic Proxy에 대해서 간단한 실습을 해보고자 한다.

Retrofit의 Dynamic Proxy

image

우선 Retrofit의 GET을 보면 런타임에 무슨 동작을 할 것이다. 라는 것을 예측할 수 있으며, 우리가 Retrofit의 create이 어떻게 이뤄지는지 보자.

image

내부 코드가 그리 길지도 않고, 이해도 금방 가는 Dynamic Proxy 패턴의 가장 좋은 예시로 보인다.

yangsooplus commented 6 months ago

인터페이스 기반 프록시와 상속 기반 프록시 패턴의 장단점

인터페이스 기반 프록시

상속 기반 프록시

7.1절에서 프록시 패턴을 통해 인터페이스에 캐싱을 추가할 수 있다고 이미 언급한 바 있다. 이번 절에서는 데커레이터 패턴을 통해 InputStream 클래스에 캐시된 읽기 기능을 추가했다. 그렇다면 캐시를 추가해야 하는 경우 프록시 패턴과 데커레이터 패턴 중 어떤 것을 선택해야 할지 생각해보자.

어댑터 패턴을 구현하는 방법에는 클래스 어댑터와 객체 어댑터의 두가지가 있다. 그렇다면 프록시 패턴과 데커레이터 패턴도 클래스 프록시 패턴, 객체 프록시 패턴 그리고 클래스 데커레이터 패턴과 객체 데커레이터 패턴처럼 두 가지 방식으로 구현할 수 있을지 생각해보자.

ldh019 commented 6 months ago

브릿지에 가려져 숨겨져있던 의외의 꿀(?) 데코레이터 패턴 Java IO 라이브러리만 읽어보면 바로 납득이 되어버렸습니다. 안드로이드 프레임워크에는 저런게 없나 고민하고 찾아봤는데 떠오르는 것도 없고 밝혀진 것도 없어서... 허허 스프링에 뭐 HTTP Call 관련해서 비슷한게 있다고는 하는데 잘 몰라요 히히

프록시 패턴

1. Java 언어 이외에 다른 언어는 동적 프록시를 어떻게 구현하는가?

    Ruby는 method_missing 콜을 인터셉트하여 구현이 가능
    예전에 오브젝트 읽을 때 Ruby에 콜 인터셉트 했던게 있던거 같아서 찾아봤는데 이런게 있었네요 
    코틀린은 Java 클래스를 이용하면 되지만, 위임 패턴을 이용해 유사한 기능을 수행할 수 있음

2. 인터페이스 기반과 상속 기반의 장단점 차이

    인터페이스의 유무에 따른 가능한 방법이 정해져 있음
    상속의 경우 결합도가 올라가지만 인터페이스는 인터페이스에 없는 메서드에 대해서는 접근이 불가능함

데코레이터 패턴

1. 캐시를 추가해야 하는 경우, 프록시와 데코레이터 중 어떤 것을 선택해야 할지 생각해보자.

    캐싱의 경우 기본 비즈니스 로직과 관련이 없는 요구사항은 아니다. 
    오히려 선택사항으로 사용자에게 제공해줄 수 있는 추가적인 관련 기능이라고 생각한다.
    그래서 데커레이터 패턴이 조금 더 적절하다고 판단된다.

어댑터 패턴

1. 어댑터 패턴도 클래스 어댑터, 객체 어댑터로 구현할 수 있을까?

    1. 프록시 패턴은 상속 기반의 프록시가 클래스 프록시, 인터페이스 기반의 프록시가 객체 프록시 라고 할 수 있을 것 같다. 
    클래스 어댑터가 상속 기반의 프록시처럼 상속 관계를 사용하고 있고, 
    인터페이스 기반의 프록시가 객체 어댑터처럼 해당 인스턴스의 함수를 호출하여 기능을 수행하고 있다.

    2. 데커레이터 패턴은 상속을 이용해서 만들면 클래스의 수 뿐만 아니라 
    한 클래스당 만들어야 할 메서드의 수가 너무 많아지기 때문에 상속이 적합하지 않다고 생각한다.

브릿지 패턴

1. 상속보다 합성이라는 설계 사상과 브릿지 패턴의 차이에 대해 알아보자.

    예시에도 나왔던 것처럼 옵션의 종류가 많거나, 옵션의 가짓수가 많은 경우 상속을 선택하는건 그냥 말이 안되기 때문에,,
    일맥상통한 부분이 있다고 할 수는 있겠다. 하지만 계층화를 위하거나, 동일한 메서드를 사용하는 것이 더욱 효율적인 경우는 
    작성자의 판단 하에 상속을 선택할 수 도 있다고 생각한다. 
    브릿지는 결국 상속보다 합성이라는 사상을 도와주기 위한 방법 중 하나인 것 같다.