GoF์ ๋์์ธ ํจํด, ํ๋ก์ ํจํด์ ๋ํด ์์๋ณธ๋ค.
ํด๋น ๊ธ์, ๋ค์์ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ดํดํ๋ ๊ฒ์ด ํธ๋ฆฌํฉ๋๋ค.
ํต์ฌ ์์ฝ
- Proxy: ๋๋ฆฌ์ธ
- ์์ ์ ์คํ์ ๋๋ฆฌ์ธ์ ํตํด ์คํํ๋๋ก ํ๋ ํจํด
- A๋ผ๋ ์์ ์ B๋ผ๋ ๋๋ฆฌ์ธ์ ํตํด ๋ณดํต ์ฑ๋ฅ์ ์ด์ ์ ์ป๊ธฐ ์ํด ์ฌ์ฉ
- ์ด ๊ณผ์ ์์ ์บ์ฑ์ ํตํด ์ฒ๋ฆฌํ๋ค๋ฉด ์บ์ฑ ํ๋ก์,
- ๊ฐ์์ ์ผ๋ก ์ฑ๋ฅ์ ๋ํ๋ค๋ฉด ๊ฐ์ ํ๋ก์๋ผ ๋ถ๋ฆ
- ํ์ง๋ง ํต์ฌ์, ๋๋ฆฌ์ธ์ ํตํด ์ด๋ ํ ์ด์ ์ ์ป๊ณ ์ถ์ ๋, ์ด๋ฌํ ํจํด์ ์ฌ์ฉํ๋ค๊ณ ์๊ฐํ๋ฉด ๋จ
๊ตฌ์กฐ

ScreenDisplay: ์ด๋ ํ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด ํ๋ฉด์ ์ถ๋ ฅํ๋ ๊ฐ์ฒด- ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์ ์ถ๋ ฅํ๊ธฐ ๊น์ง ๋๊ธฐ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๊ณ ๊ฐ์
BufferDisplay:ScreenDisplay์ ์ญํ ์ ๋์ฒดํ์ฌ ์ด๋ ํ ์ด์ ์ ์ป๊ธฐ ์ํด ๋ง๋ ProxyScreenDisplay๊ฐ์ฒด๋ฅผ ๋ด๋ถ์ ์ผ๋ก ๊ฐ์ง๊ณ ์ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ฑ๋ฅ์ ๋ํ - โ๊ฐ์โ ํ๋ก์
Display: ํ๋ฉด์ ์ถ๋ ฅํ๊ธฐ ์ํด ํ์ํ ํจ์ ์ธํฐํ์ด์ค- ํ๋์ ํ์ ์ผ๋ก ์ฒ๋ฆฌ ๊ฐ๋ฅ
์๊ฐ์ด ์ค๋๊ฑธ๋ฆฌ๋ ๊ฒฝ์ฐ ์
main
//
// main.swift
// Proxy
//
// Created by Choiwansik on 2023/01/10.
//
import Foundation
internal func main() {
let display = ScreenDisplay()
display.print(content: "์๋
")
display.print(content: "๋ ์์์ด์ผ")
display.print(content: "๋ ๊ฐ๋ฐ์์ผ")
display.print(content: "๊ทผ๋ฐ ๋ ๋ฐ์์ด ๋ ์ข๋๋ผ")
display.print(content: "๊ณ๋์ ํ๋ผ์ด๊ฐ ๋ ๋ง์์ด")
display.print(content: "์คํฌ๋จ๋ธ์ ๋ฒํฐ๋ฅผ ๊ผญ ๋นผ์ค")
display.print(content: "๊ทธ๋ผ ์๋
")
}
main()
Display
//
// Display.swift
// Proxy
//
// Created by Choiwansik on 2023/01/10.
//
import Foundation
internal protocol Display {
func print(content: String)
}
ScreenDisplay
//
// ScreenDisplay.swift
// Proxy
//
// Created by Choiwansik on 2023/01/10.
//
import Foundation
internal class ScreenDisplay: Display {
internal func print(content: String) {
// content๋ผ๋ ๋ฌธ์์ด์ ํ๋ฉด์ ํ์ํ๋ ค๋ฉด ์๋นํ ์๊ฐ์ด ์์๋๋ค๊ณ ๊ฐ์
Thread.sleep(forTimeInterval: 0.5)
Swift.print(content)
}
}
๊ฒฐ๊ณผ
์๋
๋ ์์์ด์ผ
๋ ๊ฐ๋ฐ์์ผ
๊ทผ๋ฐ ๋ ๋ฐ์์ด ๋ ์ข๋๋ผ
๊ณ๋์ ํ๋ผ์ด๊ฐ ๋ ๋ง์์ด
์คํฌ๋จ๋ธ์ ๋ฒํฐ๋ฅผ ๊ผญ ๋นผ์ค
๊ทธ๋ผ ์๋
Program ended with exit code: 0
- ํ์ค์ฉ ์ฒ์ฒํ ์ถ๋ ฅ๋จ
- ์ด๋ ScreenDisplay์
print(content:)๋ฉ์๋๊ฐ ์ถ๋ ฅ์ ์ํด ์ค๋น์๊ฐ์ด ์ค๋๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์ - ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ์ถ๋ ฅํ ๋ฐ์ดํฐ๋ฅผ ์ต๋ํ ๋ชจ์์ print ๋ฉ์๋๋ฅผ ์ต์ํ์ผ๋ก ํธ์ถํด์ฃผ๋ฉด ๋จ
Proxy๋ฅผ ํตํ ํด๊ฒฐ
main
//
// main.swift
// Proxy
//
// Created by Choiwansik on 2023/01/10.
//
import Foundation
internal func main() {
// notUsingProxy()
usingProxy()
}
internal func notUsingProxy() {
let display: Display = ScreenDisplay()
display.print(content: "์๋
")
display.print(content: "๋ ์์์ด์ผ")
display.print(content: "๋ ๊ฐ๋ฐ์์ผ")
display.print(content: "๊ทผ๋ฐ ๋ ๋ฐ์์ด ๋ ์ข๋๋ผ")
display.print(content: "๊ณ๋์ ํ๋ผ์ด๊ฐ ๋ ๋ง์์ด")
display.print(content: "์คํฌ๋จ๋ธ์ ๋ฒํฐ๋ฅผ ๊ผญ ๋นผ์ค")
display.print(content: "๊ทธ๋ผ ์๋
")
}
internal func usingProxy() {
let display: Display = BufferDisplay(bufferSize: 5)
display.print(content: "์๋
")
display.print(content: "๋ ์์์ด์ผ")
display.print(content: "๋ ๊ฐ๋ฐ์์ผ")
display.print(content: "๊ทผ๋ฐ ๋ ๋ฐ์์ด ๋ ์ข๋๋ผ")
display.print(content: "๊ณ๋์ ํ๋ผ์ด๊ฐ ๋ ๋ง์์ด")
display.print(content: "์คํฌ๋จ๋ธ์ ๋ฒํฐ๋ฅผ ๊ผญ ๋นผ์ค")
display.print(content: "๊ทธ๋ผ ์๋
")
guard let bufferDisplay = display as? BufferDisplay else {
return
}
bufferDisplay.flush()
}
main()
BufferDisplay
//
// BufferDisplay.swift
// Proxy
//
// Created by Choiwansik on 2023/01/10.
//
import Foundation
internal class BufferDisplay: Display {
internal init(bufferSize: Int) {
self.bufferSize = bufferSize
}
internal func print(content: String) {
self.buffer.append(content)
if self.buffer.count == self.bufferSize {
self.flush()
}
}
internal func flush() {
if self.screen == nil {
self.screen = ScreenDisplay()
}
let lines = self.buffer.joined(separator: "\n")
Swift.print(lines)
self.buffer.removeAll()
}
private var buffer = [String]()
private let bufferSize: Int
private var screen: ScreenDisplay?
}ScreenDisplay๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋๋ฆฌ์์ธBufferProxy๋ฅผ ์ฌ์ฉํ์ฌ ์๋๋ฅผ ๋์- ๋ค๋ง 5๊ฐ์ฉ ์ฒ๋ฆฌํ๋ค๋ ์ ๋๋ฌธ์ ๋ง์ง๋ง์ ๋ช
์์ ์ผ๋ก
flush๋ฅผ ํธ์ถํด์ฃผ์ด์ผ ํจ
๋๊ธฐ
- ์บก์ํ์ ๊ด์ ์์ ๋ณด์์ ๋, ๋ด๋ถ ๊ฐ์ฒด์ ์์ฑ๊ณผ ์ด๊ธฐํ ๊ฐ์ ๋ถ๋ถ์ ํด๋ผ์ด์ธํธ ์ชฝ์์๋ ๋ชจ๋ฅด๋ ๊ฒ์ด ์ข๋ค.
- ํ์ง๋ง ๊ฐ์ฒด ์์ฑ๊ณผ ์ด๊ธฐํ์ ์์ด ๋ง์ ์๊ฐ์ด ์์๋๋ค๋ฉด, ํด๋ผ์ด์ธํธ์์ ์ด๋ฅผ ์ ์ดํ๊ณ ์ถ์ ์ ์๋ค.
- ์ฌ์ฉํ์ง๋ ์๋ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํด๋๋ ๊ฒฝ์ฐ
- ์ด๋ด ๊ฒฝ์ฐ Proxy๋ผ๋ ๋๋ฆฌ์ธ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด, ๊ฐ์ฒด ์์ฑ ํ์ด๋ฐ์ ์ ์ดํ ์ ์๋๋ก ํ๋ฉด ์ง์ ๋ถํ ์ฝ๋๊ฐ ์ฌ๋ผ์ง๋ค.
- ๊ฐ์ฒด ์์ฑ์ ์ฑ ์์ Proxy๊ฐ ๋ด๋นํ๊ธฐ ๋๋ฌธ์.
- ์๋ฅผ ๋ค์ด, ์ง์ ์ด๋ฏธ์ง ๋ก๋๋ฅผ ํด์ ํด๋ผ์ด์ธํธ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ์๋๊ณ ,
- ์ค๊ฐ์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋๊ณ , ์ด๋ฅผ ํตํด ์ ๊ทผํจ์ผ๋ก์จ ์ค์ ์ฌ์ฉ์์ ์ ๋ช ํํ ํด๋๋ ๊ฒ.
ํ์ฉ์ฑ
- Remote Proxy
- ์๋ก ๋ค๋ฅธ ์ฃผ์ ๊ณต๊ฐ์ ์กด์ฌํ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ํ ๊ฐ์ฒด๋ก, ๋ก์ปฌํ๊ฒฝ์ ์์น
- ์๋ง ์์ฒด์ ์ผ๋ก ๊ฐ์ฒด๋ฅผ ์ ํํ๊ธฐ ์ํ ๋ชฉ์ ์ธ ๋ฏ ํจ
- Virtual Proxy
- imageProxy
- ์์ฒญ์ด ์์ ๊ฒฝ์ฐ์๋ง ๊ณ ๋น์ฉ ๊ฐ์ฒด๋ฅผ ์์ฑ
- ์บ์ฑ์ด ๋ค์ด๊ฐ ์๋?
- Protection Proxy
- ์๋ ๊ฐ์ฒด์ ๋ํ ์ค์ ์ ๊ทผ์ ์ ์ด
- ๊ฐ์ฒด๋ณ๋ก ์ ๊ทผ ์ ์ด ๊ถํ์ด ๋ค๋ฅผ ๊ฒฝ์ฐ ์ฌ์ฉ
- Smart reference(Smart Pointer)
- ์ฐธ์กฐ ํ์๋ฅผ ์ ์ฅํ๋ค๊ฐ ๋๋ ์ฐธ์กฐ๊ฐ ์์ ๊ฒฝ์ฐ ๊ฐ์ฒด๋ฅผ ์๋์ผ๋ก ์์ฐ
- ์ฒ์ ์ฐธ์กฐ๋๋ ์์ ์ Persistence์์ memory๋ก ๋ก๋ํจ
- ๊ฐ์ฒด ์ ๊ทผ ์ ์ ๋ค๋ฅธ ๊ฐ์ฒด๊ฐ ์ ๊ทผํ ๊ฒ์ ๊ณ ๋ คํ์ฌ lock์ ๊ฑบ
๊ฒฐ๊ณผ
- ํ๋ก์ ํจํด์ ์ฌ์ฉํ๋ฉด, ํน์ ๊ฐ์ฒด์ ์ ๊ทผํ ๋ ์ถ๊ฐ์ ์ธ ํต๋ก๋ฅผ ์ ๊ณตํ๊ฒ ๋จ
- ์ด ํต๋ก์์๋ ์ด๋ค ๋ชฉ์ ์ ์ด๋ฃจ๋๋์ ๋ฐ๋ผ ์ฑ
์์ ๊ฐ์ง
- ์๊ฒฉ: ๊ฐ์ฒด๊ฐ ๋ค๋ฅธ ์ฃผ์ ๊ณต๊ฐ์ ์๋ ๊ฒ์ ์จ๊ธธ ์ ์์
- ๊ฐ์: ๊ฐ์ฒด ์์ฑ์ ๋ํ ์ฒ๋ฆฌ์ ์ต์ ํ
- ๋ณดํธ/์ค๋งํธ: ๊ฐ์ฒด ์ ๊ทผ์ ๋ฐ๋ฅธ ์ถ๊ฐ์ ์ธ ๊ด๋ฆฌ(๋ฉ๋ชจ๋ฆฌ, ๊ถํ, ์์ฑ๊ณผ ์ญ์ )
- Copy on write
- ์ค์ ๋ณ๊ฒฝ(ํน์ ์ฐ๊ธฐ)๊ฐ ์ผ์ด๋ ๊ฒฝ์ฐ์๋ง ๊ฐ์ ๋ณต์ฌํจ
- ์ด๊ฑธ ๊ฐ๋ฅํ๊ฒ ํ๋ ค๋ฉด ์๋ณธ์ ๋ํ ์ฐธ์กฐ ๊ฐ์๋ฅผ ๊ด๋ฆฌํด์ผ ํจ
- ๋ง์ฝ ๋ณ๊ฒฝ์ด ์ผ์ด๋ฌ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ์์
์ ํด์ผํ๊ธฐ ๋๋ฌธ
- ๋ณต์ฌ
- ์๋ณธ์ ์ฐธ์กฐ ์นด์ดํธ -1
- ๋ณ๊ฒฝ๋ ๊ฐ์ ๊ฐ๊ณ ์ถ์ ๋ณ์์ 1๋ฒ ํญ๋ชฉ์ ํ ๋น
- ๋ง์ฝ ๋ณ๊ฒฝ์ด ์ผ์ด๋ฌ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ์์
์ ํด์ผํ๊ธฐ ๋๋ฌธ
- ๊ฐ์ฒด์ ํฌ๊ธฐ๊ฐ ํฌ๋ฉด ํด์๋ก ํด๋น ์์ ์ ๋ณต์ฌ ๋น์ฉ์ ํ๊ฒฉํ๊ฒ ์ค์ฌ์ค
์๊ฐํด๋ณผ ์
- Copy on write๋ Proxy Pattern์ด๋ค.
- Proxy๋ lazy, eager loading๊ณผ ๊ด๋ จ์ด ์๋ค.
- ๊ฐ ์ํฉ์ ๋ง๋๋ก ์ฒ๋ฆฌํด์ผ์ง ๋ฌด์กฐ๊ฑด์ ์ผ๋ก ํ๋ก์ ํจํด์ด ์ข์ ๊ฒ์ ์๋๋ค.
- ํจํด ์์ฒด๋ฅผ ์๋ ๊ฒ๋ณด๋ค, ๋ฌธ์ ์ํฉ์ด ๋ฌด์์ธ์ง, ์ด๋ป๊ฒ ์ ์ฉํ๋ ๊ฒ์ด ํ ํ๋ก์ ํธ์ ์ข์์ง๋ฅผ ๊ณ ๋ฏผํ๋ ๊ฒ์ด ๋ ์ข๋ค๊ณ ์๊ฐํ๋ค.