안녕하세요! 오늘은 소프트웨어 개발에서 자주 사용되는 디자인 패턴 중 하나인 "프록시 패턴"에 대해 이야기해보려고 합니다.
프록시 패턴은 어떤 객체의 대리자 역할을 하는 객체를 생성하여 사용하는 방식으로, 코드의 유연성과 재사용성을 높이는 데 도움이 됩니다.
우선, 프록시 패턴에 대해 알아보기 전에 프록시라는 단어부터 알아보겠습니다.
'프록시'란 우리가 일상 생활에서 종종 마주치는 대리인이나 중개인을 의미합니다.
예를 들어, 외국에 살고 있는 친구에게 선물을 보내려면 그 나라의 대리점을 통해서 보내는 것과 비슷한 개념입니다.
이와 같이 프록시 패턴도 실제 객체의 역할을 수행하지만, 클라이언트와 실제 객체 사이에 중간 계층으로서 동작합니다.
프록스 패턴이란?
프록시 패턴은 이름에서 알 수 있듯이, 어떤 다른 것의 '대리'를 맡는 객체를 만드는 디자인 패턴입니다. 이 '대리' 객체가 바로 프록시입니다.
실제 객체와 동일한 인터페이스를 가지고 있어서 사용자는 실제 객체와 프록시를 구분하지 않고 사용할 수 있습니다.
그럼 왜 굳이 대리인을 만들어서 사용하나요? 여러 가지 이유가 있는데요. 그 중 몇 가지를 한 번 살펴보겠습니다.
프록시 패턴을 사용하는 이유
- 보안: 실제 객체에 직접 접근하는 것을 제한하고 검증 과정을 거친 후에만 접근할 수 있게 할 때 사용
- 성능: 크기가 큰 리소스를 로딩할 때, 필요한 시점에서만 로딩하기 위해서 사용
- 네트워크 연결: 원격 위치에 있는 리소스에 접근할 때 네트워크 연결과 관련된 작업을 처리하기 위해서 사용
위와 같은 이유 외에 다양한 목적으로 프록시 패턴을 사용하게 됩니다.
예제로 살펴보기
간단한 예제로 한 번 설명해볼게요. 우선 Image라는 인터페이스와 RealImage라는 클래스가 있다고 생각해 봅시다.
protocol Image {
func display()
}
class RealImage: Image {
private let filename: String
init(filename: String) {
self.filename = filename
loadFromDisk()
}
func display() {
print("Displaying \(filename)")
}
private func loadFromDisk() {
print("Loading \(filename)")
}
}
여기서 RealImage 클래스의 생성자에서 이미지 파일(loadFromDisk())를 로드하는 작업이 일어나고, display() 메소드를 호출하면 이미지가 출력됩니다.
그런데 여기서 문제점은 무엇일까요? 바로 '필요할 때'가 아니라 '객체를 생성하는 시점'에 이미지를 로드한다는 점입니다. 이럴 경우, 이미지가 필요하지 않은 상황에서도 불필요하게 리소스를 소모하게 되죠.
이런 문제를 해결하기 위해 프록시 패턴을 사용합니다.
ProxyImage라는 클래스를 만들어 보겠습니다.
class ProxyImage: Image {
private let filename: String
private var realImage: RealImage?
init(filename: String) {
self.filename = filename
}
func display() {
if realImage == nil {
realImage = RealImage(filename: filename)
}
realImage?.display()
}
}
ProxyImage 클래스는 RealImage와 같은 인터페이스(display())를 가지고 있습니다. 그러나 실제 이미지 로딩 작업은 사용자가 처음으로 이미지를 보려고 할 때(display() 메소드 호출 시) 이루어집니다.
이렇게 프록시 패턴을 사용하면, 리소스의 효율적인 사용과 성능 최적화에 도움이 됩니다. 또한, 원본 객체의 복잡성을 감추고 클라이언트 코드에서 원본 객체에 대한 직접적인 의존성을 줄여준다는 장점이 있습니다!
감사합니다.
틀린 부분이 있거나 더 좋은 내용 훈수 환영합니다!
공감과 댓글 부탁드립니다.
'CS > 디자인 패턴' 카테고리의 다른 글
[디자인패턴] MVC 패턴 이해하고 활용하기 (0) | 2024.01.15 |
---|---|
[디자인패턴] 이터레이터 패턴 With Swift, Java (0) | 2023.10.29 |
[디자인패턴] 옵저버 패턴(Observer Pattern) (2) | 2023.10.21 |
[디자인 패턴] 팩토리 패턴과 전략 패턴의 개념과 예제 소스 (2) | 2023.10.02 |
[디자인 패턴] 디자인 패턴과 싱글톤 패턴 (2) | 2023.05.24 |