[Swift] 디자인 패턴 - Proxy Pattern

yeton·2023년 1월 18일
0
post-custom-banner

Proxy Pattern

  • 실제 기능을 수행하는 객체(Real Object) 대신 가상의 객체(Proxy Object)를 사용해 로직의 흐름을 제어하는 디자인 패턴
  • 프록시 객체를 표현하자면 어떤 객체가 존재하지만, 해당 객체를 바로 사용하기엔 부담이 되는 경우에는 프록시 객체를 통해 처리를 하고 해당 객체가 반드시 필요한 시점에야 비로소 해당 객체를 생성하여 사용하겠다는 의미이다.

Proxy Pattern, 언제 쓰나요?

  • 어떤 객체가 실제로 사용될 때까지 생성 및 초기화를 위한 처리를 미루는 것이다.
  • 예를 들어 화면에 다양한 객체가 있는 앱을 실행할 때를 생각해보자. 화면은 스크롤할 수 있는데, 사진도 있고, 다양한 콘텐츠들이 있어서 이를 모두 로드한 뒤 앱을 실행하려면 시간이 너무 많이 걸리게 된다. 실제로 화면에 보이는 콘텐츠는 몇 개 없을 텐데 말이다.
  • 즉, 이럴 때 프록시 패턴을 사용하여 해당 콘텐츠가 실제 화면에 나타났을 때 해당 콘텐츠를 로드하라고 전달해주면 실제로 사용할 때 해당 객체를 생성하게 된다. 즉 바로 생성하는 것이 아닌 생성을 지연시키고 싶을 때 사용하는 것이 프록시 패턴이다.

프록시 패턴을 UML로 도식화하면 아래와 같습니다.

https://i.imgur.com/YfGZN24.png

  • 프록시 패턴을 실생활에서 예시로 보면 아래와 같은 현상을 볼 수 있습니다. https://i.imgur.com/V6k3qr9.png

🐻 예제를 봅시당

https://i.imgur.com/PsAA1xn.jpg

  • Subject: client가 직접 접근하여 기능을 수행하는 추상 부모 클래스, 해당 클래스를 RealSubject가 상속을 받아서 실제 기능에 대한 구현을 수행한다.
// Subject (Service Interface)
protocol YoutubeService {
    func showPreview()
}
  • RealSubject: 실제 기능을 수행하는 객체, 회사 대표
// Real Service
class YoutubeVideo: YoutubeService {

    private var id: Int
    private var name: String

    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }

    func showPreview() {
        print("\\(name) Preview Play 😀\\n")
    }
}
  • Proxy: RealSubject 객체 대신에 기능을 위임받아 수행하는 역할을 하는 객체, 해당 Proxy 객체가 실제 객체의 기능 및 추가적인 기능을 수행한다.
// Proxy
class YoutubeVideoProxy: YoutubeService {

    private var youtubeVideo: YoutubeService?

    private var id: Int
    private var name: String
    private var client: Client

    init(id: Int, name: String, client: Client) {
        self.id = id
        self.name = name
        self.client = client
    }

    func showTitle() { // 실제 비디오 객체가 없더라도 보여줄 수 있는 메서드
        print("\\(id), \\(name) Youtube Video")
    }

    func showPreview() { // 비디오 객체가 필요
        if let youtubeVideo = self.youtubeVideo {
            youtubeVideo.showPreview()
        } else {
            loadVideoInfo()
            self.youtubeVideo?.showPreview()
        }
    }

    private func loadVideoInfo() { // 비디오 객체가 필요할 때 로드할 수 있는 메서드
        print("load Video...🐧")
        self.youtubeVideo = YoutubeVideo(id: self.id, name: self.name)
    }
}
  • 실행
let owner = Client(auth: .owner)
let ownerProxy = YoutubeVideoProxy(id: 1, name: "🦋잔나비🦋", client: owner)

ownerProxy.showTitle()
ownerProxy.showPreview()

스크린샷 2022-09-21 오전 9.00.50.png

Proxy Pattern, 장점과 단점은요?

장점

  • 프록시는 서비스 객체가 준비되지 않았거나 사용할 수 없는 경우에도 작동합니다.
  • 서비스나 클라이언트를 변경하지 않고 새로운 프록시를 도입할 수 있습니다.

단점

  • 새로운 클래스를 도입해야 하므로 코드가 복잡해집니다.
  • 응답이 지연될 수 있습니다.
profile
🤗제 깃허브 링크는 https://github.com/yeeton37🤗
post-custom-banner

0개의 댓글