구조 패턴 - proxy
Closed this issue · 0 comments
EunHee-Jeong commented
구조 패턴 - Proxy란?
- 원본 객체는 숨기고, 대신 동작하는 객체의 제한된 접근으로 컨트롤하는 디자인 패턴
- 원본 객체에 대한 동일한 인터페이스를 제공한다.
- 객체에 접근할 때, 원본 객체의 클라이언트 대신 proxy를 사용한다. 대리자 개념인 셈이다.
- 원본 객체의 요청 전후로, proxy는 자신의 logic을 주입한다.
lazy
초기화와 객체에 대한 접근을 보호할 수 있다.
가장 흔한 예시
1. Remote Proxy
- 주로 웹 서비스에서 이용한다.
- 예시를 들자면 네트워크를 통해 request를 차례로 전달하는 프록시를 사용하는 것 …
- 네트워크 호출의 복잡성을 줄일 수 있다.
- remote 서비스를 local 개념으로 사용할 수 있게 해준다.
2. Virtual Proxy
-
말 그대로 가상 프록시다.
-
첫 사용 전까지 원본 객체의 생성을 지연시킨다.
⇒
lazy
초기화 (Swift에서 built-in으로 제공하기는 함)
3. Protective Proxy
- 민감한 객체로의 접근을 제어한다.
- 보호하고자 하는 객체에 request를 위임하기 전에 먼저 프록시가 호출자를 확인한다.
코드 예시
소스 코드
import Foundation
public protocol DataBaseController {
func save()
func undo()
}
// 프로토콜을 채택할 타입 정의.
public class CoreDataManager: DataBaseController {
public init() {
// 객체 생성
sleep(3) // 확인을 위해 시간 걸어줌
}
public func save() {
print("All changes saved")
}
public func undo() {
print("All changes reverted")
}
}
// 팩토리 메서드 선언
public func makeDatabaseController() -> DataBaseController {
CoreDataManager()
}
// proxy
public class CoreDataProxy: DataBaseController { // 같은 인터페이스 가짐을 확인 가능
private var realManager: CoreDataManager? // proxy
private var coreDataManager: CoreDataManager? {
guard let result = realManager else {
realManager = CoreDataManager()
return realManager
}
return result
}
private lazy var coreDataManager2: CoreDataManager? = CoreDataManager()
// lazy는 계산 속성을 넣을 수 없기 때문에 옵셔널 체이닝으로 선언했음
// ⬆️ 클라이언트가 메서드를 처음 호출하는 시점에 계산됨 (Virtual Proxy에 해당)
/*
무거운 객체의 자원을 곧장 생성하는 대신에,
실제로 필요할 때까지만 초기화를 지연시켜
최종 수정이 필요한 경우에만 팩토리 메서드가 프록시 인스턴스를 반납하고 원본 객체를 사용하도록 동작함
*/
public func save() {
coreDataManager.save()
print("All changes saved")
}
public func undo() {
coreDataManager.undo()
print("All changes reverted")
}
}
실행 부분
import Foundation
// database controller 객체 simulate
print("App 로딩 중 . . .")
let dbController = makeDatabaseController()
print("준비")
// ...
//dbController.save()
// 즉 지연 초기화를 통해 App의 로딩시간을 향상시킬 수 있다.
// 실제로 필요할 때만 사용하기 때문
let contextChanged = false
if contextChanged {
dbController.save()
}
dbController.undo()
dbController.save()
정리
-
정리하자면, proxy 디자인 패턴은 실제 객체를 placeholder (= 자리 표시자) 뒤에 숨긴다 !
-
주로 사용되는 proxy들
- Remote Proxy
- remote 객체의 local placeholder로서 동작
- Virtual Proxy
- 크기가 거대한 자원의 생성을 관리
- 첫 접근 이전까지 생성을 지연시키는 방식
- Protective Proxy
- 보호된 자원에 접근하기 전에, 호출이 허가되었는지 확인
- Remote Proxy
-
주의점
- proxy로 인해 client 측의 변화가 당겨져서는 안 된다.