๋ฐ์ํ
Proxy Pattern - ํ๋ก์ ํจํด
Proxy Pattern์ ์ฃผ๋ก ๊ฐ์ฒด์ ์ ๊ทผ์ ์ ์ดํ๊ฑฐ๋ ๊ฐ์ฒด์ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
- ์ด ํจํด์ ์ฃผ์ฒด(Real Subject)์ ๊ทธ ์ฃผ์ฒด์ ๋ํ ๋๋ฆฌ์(Proxy)๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
- Proxy๋ ๋๋ฆฌ์ธ ์ด๋ผ๋ ์๋ฏธ, ์ผ์ ๋์ ํ๋ ์ฌ๋์ด๋ผ๋ ์๋ฏธ์ ๋๋ค.
- ‘๋๋ฆฌ์ธ proxy’์ด ํ ์ ์๋ ๋ฒ์๋ฅผ ๋๋ ์ผ์ด ๋ฐํํ๋ฉด, ์ค์ ‘๋ณธ์ธ real’ ์๊ฒ ์์ ์ ๋ฌด์์ฒญ์ ํ๋ค๋ ํน์ง์ด ์์ต๋๋ค.
- ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์์๋ ๋ฐ๋น ์ ์ผ์ ํ ์ ์๋ ‘real object’ ๋์ ์ ‘proxy object’๊ฐ ์ด๋์ ๋ ์ผ์ ์ฒ๋ฆฌํ๊ธฐ๋ ํฉ๋๋ค.
- ๊ทธ๋ฆฌ๊ณ real ์ค๋ธ์ ํธ๋ proxy ์ค๋ธ์ ํธ์ ์กด์ฌ๋ฅผ ๋ชจ๋ฆ
๋๋ค.
- ์ฆ, ์ด๋ง์ ์์ ์ด proxy๋ฅผ ๊ฒฝ์ ํด์ ํธ์ถ๋๊ณ ์๋์ง ์ง์ ํธ์ถ๋๊ณ ์๋์ง ๋ชจ๋ฅธ๋ค๋ ์๋ฏธ์ ๋๋ค.
- ์ด์ ๋ real ์ค๋ธ์ ํธ์ proxy ์ค๋ธ์ ํธ๋ ์๋ก ๊ตฌ์กฐ์ ๋ถ๋ฆฌ๊ฐ ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ๋ฐ๋ฉด์, ‘proxy ์ค๋ธ์ ํธ’๋ ‘real ์ค๋ธ์ ํธ’๋ฅผ ์๊ณ ์๋ค๋ ํน์ง์ด ์์ต๋๋ค.
Proxy Pattern์ ์ข ๋ฅ
- ๊ฐ์ ํ๋ก์(Virtual Proxy): ๊ฐ์ฒด์ ์์ฑ์ด ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ฒฝ์ฐ, ์ค์ ๊ฐ์ฒด๋ฅผ ํ์ํ ๋๊น์ง ์์ฑํ์ง ์๊ณ ๋์ Proxy๋ฅผ ์ฌ์ฉํฉ๋๋ค. Proxy๋ ์ค์ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋๊น์ง ๊ทธ ๊ฐ์ฒด์ ์ญํ ์ ๋์ ํฉ๋๋ค.
- ์๊ฒฉ ํ๋ก์(Remote Proxy): ๋ค๋ฅธ ์ฃผ์ ๊ณต๊ฐ์ ์๋ ๊ฐ์ฒด๋ฅผ ๋ก์ปฌ์์ ์ฌ์ฉํ ์ ์๋๋ก ํด์ค๋๋ค. ์ด๋ ๋ถ์ฐ ์์คํ ์์ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค.
- ๋ณดํธ ํ๋ก์(Protection Proxy): ๊ฐ์ฒด์ ๋ํ ์ ๊ทผ ๊ถํ์ ์ ์ดํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํน์ ์ฌ์ฉ์๊ฐ ํน์ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋๋ก ํ ์ ์์ต๋๋ค.
- ์บ์ฑ ํ๋ก์(Caching Proxy): ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถ๋๋ ๊ฐ์ด๋ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค.
Proxy Pattern์ ๊ตฌ์กฐ
Proxy Pattern์ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ง๋๋ค.
- Subject(์ฃผ์ฒด)์ ์ญํ : Proxy์, RealSubject์ ์ญํ ์ ๋์ผ์ํ๊ธฐ ์ํ ์ธํฐํ์ด์ค๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. → ๋ผ๋์ ๋๋
- Proxy(๋๋ฆฌ์ธ)์ ์ญํ : Client์ ์๊ตฌ๋ฅผ ํ ์ ์๋ ๋งํผ ์ฒ๋ฆฌํฉ๋๋ค, ๊ทธ๋ฌ๋ ์ฒ๋ฆฌํ ์ ์์ผ๋ฉด Real Subject์๊ฒ ์ฒ๋ฆฌ๋ฅผ ๋งก๊น๋๋ค.
- Real Subject(์ค์ ์ ์ฃผ์ฒด)์ ์ญํ : Proxy๊ฐ ๊ฐ๋นํ ์ ์๋ ์ผ์ด ๋ฐ์ํ์ ๋ ์ฒ๋ฆฌํ๋ ์ญํ ์ ๋ด๋นํฉ๋๋ค.
- Client(์๋ขฐ์ธ)์ ์ญํ : Proxyํจํด์ ์ด์ฉํ๋ ์ญํ ์ ๋๋ค.
- ์ค์ ๋ก Server ๊ตฌ์ฑ์, Server์์ Proxy ๋๋๊ฒ ์ผ๋ฐ์ ์ ๋๋ค.
- Proxy๋ Server์ Communicationํ๋ฉด์ Client์๊ฒ ํ์ํ ์ ๋ณด๋ฅผ ์ฃผ๋ ๊ธฐ๋ฅ์ ๋ด๋นํฉ๋๋ค.
- ์ด์ธ์๋ log, statics ๊ธฐ๋ฅ์ด ์กด์ฌํฉ๋๋ค.
- ํน์ Server์ log๋ฅผ ์ค์ด๊ธฐ ์ํด ๋ค์ด์ค๋ requests์ ๋ํ response๋ฅผ cache๋ก ๊ฐ์ง๊ณ ์๊ธฐ๋ ํฉ๋๋ค.
- Client๊ฐ ์์ฃผ ์์ฒญํ๋ request๊ฐ์ ๊ฒฝ์ฐ๋ proxy์์ ๋ฐ๋ก response๋ฅผ ์ฃผ๋๊ฒ ๊ฐ๋ฅํฉ๋๋ค.
์์ ๊ฐ์ ๊ฐ๋ ๋ค์ด Proxy Pattern์๋ ๋๊ฐ์ด ์ ์ฉ์ด ๋ฉ๋๋ค.
- ๋ง์ฝ์ ์ฌ์ฉํ๊ณ ์ ํ๋ Object๊ฐ ์๊ณ , ๊ทธ Object๋ฅผ ์ฌ์ฉํ๋ Client๊ฐ ์์ต๋๋ค.
- ์ด๋ Client๊ฐ Object์ ์ด๋ ํ ๊ธฐ๋ฅ์ ์คํ์ํค๋ ค๊ณ ํ๋ฉด Proxy์์๋ Object์ Function์ ์คํ์ํค๊ฑฐ๋, ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๊ฑฐ๋ Object์ ๊ฒฐ๊ณผ๋ฅผ cache๋ก ๊ฐ์ง๊ณ ์๋ ๊ธฐ๋ฅ์ ํ ์ ์์ต๋๋ค.
Proxy Pattern์ ์ฅ์ & ๋จ์
- Proxy Pattern์ ์ฅ์
- ๊ฐ์ฒด์ ๋ํ ์ ๊ทผ ์ ์ด: proxy๋ ์ฃผ์ฒด์ ๋ํ ์ ๊ทผ์ ์ ์ดํ๊ณ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ์ง์ฐ ์ด๊ธฐํ: ๋น์ฉ์ด ๋ง์ด ๋๋ ๊ฐ์ฒด์ ์์ฑ์ ์ง์ฐ์ํฌ ์ ์์ต๋๋ค.
- ์ถ๊ฐ ๊ธฐ๋ฅ: proxy๋ ์ฃผ์ฒด์ ๋ฉ์๋ ํธ์ถ ์ ํ์ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
- Proxy Pattern์ ๋จ์
- ๋ณต์ก์ฑ ์ฆ๊ฐ: proxy๋ฅผ ์ถ๊ฐํ๋ฉด ์ฝ๋๊ฐ ๋ณต์กํด์ง ์ ์์ต๋๋ค.
- ์ฑ๋ฅ ์ค๋ฒํค๋: proxy๋ฅผ ํตํด ์์ฒญ์ด ์ ๋ฌ๋๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ์ ์ฑ๋ฅ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
Proxy Pattern - Example.1
class Cat:
def speak(self):
print("meow")
kitty = Cat()
kitty.speak() # meow
- Cat class๋ Speak ํจ์๊ฐ ์กด์ฌํฉ๋๋ค.
- Cat object์ธ kitty๋ฅผ ๋ง๋ค๊ณ kitty๋ speak์ ํ ์ ์์ต๋๋ค.
class CatProxy:
def __init__(self, cat:Cat):
self.cat = cat
def speak(self):
print("before speak") # validity Check
self.cat.speak()
print("after speak") # logging
- CatProxy๋ ๋ด๋ถ์ Cat object๋ฅผ property๋ก ๊ฐ์ง๊ณ ์์ผ๋ฉฐ Cat์ ๋ํํ๊ธฐ ๋๋ฌธ์ ๋์ผํ speakํจ์๋ฅผ ๊ฐ์ง๊ณ ์์ด์ผ ํฉ๋๋ค.
- (Proxy pattern์ ํน์ฑ์ ๊ธฐ์กด Object์ธ Cat๊ณผ Proxy object๊ฐ ๋์ผํ interface๋ฅผ ๊ฐ์ง๊ณ ์์ด์ผํจ)
- CatProxy์ speak์์๋ ๊ทธ ๋ชฉ์ ์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
kitty_proxy = CatProxy(kitty)
kitty_proxy.speak()
# Result
before speak
meow
after speak
- CatProxy object์ธ Kitty_proxy๋ฅผ ๋ง๋ค๊ณ cat object์ธ kitty๋ฅผ ์ธ์๋ก ๋๊ฒจ์ค์ speak๋ฅผ ํธ์ถ ์, ๊ฒฐ๊ตญ Cat class์ speakํจ์๋ฅผ ์ด์ฉํ ์ ์์ต๋๋ค.
Client๊ฐ ์ด๋ค object๋ฅผ ์ง์ ์ฌ์ฉํ๊ธฐ๋ณด๋ค๋ ๊ฐ์ interface๋ฅผ ๊ฐ์ง ๋ค๋ฅธ object๋ฅผ ํตํด์ ์ฌ์ฉํ๋ ๊ฒ์ด ํ์ํ ๋, Proxy Pattern์ ๊ณ ๋ คํด๋ณผ ์ ์์ต๋๋ค.
Proxy Pattern - Example.2
- Subject(์ฃผ์ฒด)์ ์ญํ → Printable
- Proxy(๋๋ฆฌ์ธ)์ ์ญํ → PrinterProxy
- RealSubject(์ค์ ์ ์ฃผ์ฒด)์ ์ญํ → Printer
- Client(์๋ขฐ์ธ)์ ์ญํ → Main
import time
from abc import *
from asyncio.windows_events import NULL
class Printable(metaclass = ABCMeta):
def __init__(self):
self._name = ""
@abstractmethod # ๋ผ๋
def setPrinterName(self):
pass
@abstractmethod # ๋ผ๋
def getPrinterName(self):
pass
@abstractmethod # ๋ผ๋
def printText(self):
pass
class Printer(Printable): # Real
def __init__(self, name):
self._name = name
self.heavyJob("Printer์ ์ธ์คํด์ค("+self.name+")๋ฅผ ์์ฑ ์ค") # ์ด๊ธฐํ ์ญํ
def setPrinterName(self, name):
self._name = name
def getPrinterName(self):
return self._name
def printText(self, msg):
print("==="+self.name"===", end=": ")
print(msg)
def heavyJob(self, msg): # ๋ถํ
print(msg)
for i in range(5):
time.sleep(1)
print("์๋ฃ")
class PrinterProxy(Printable):
def __init__(self, name):
self._name = name
self._real = NULL
def realize(self):
if self._real == NULL:
self._real = Printer(self._name) # ๋ถํ
์ญํ
def setPrinterName(self, name):
if self._real != NULL:
self._real.setPrinterName(name) # ๋ถํ
ํ
self._name = name
def getPrinterName(self):
return self._name
def printText(self, msg): # ๋ง์ฝ์ ๋๋ฆฌ์ธ์ ์ญํ ๋ฒ์ ์ด๊ณผ์, realize์์ ์คํ
self.realize()
self._real.printText(msg)
# client
p = PrinterProxy("๋ณด์คํ ํฌ")
print("ํ์ฌ ์ด๋ฆ์ "+p.getPrinterName()+"์
๋๋ค.")
p = PrinterProxy("๋จธํ๋ฆฌ")
print("ํ์ฌ ์ด๋ฆ์ "+p.getPrinterName()+"์
๋๋ค.")
p.printText("hello, How are you?")
p.printText("Do you hear me?")
p.setPrinterName("์ํด๋ก")
print("ํ์ฌ ์ด๋ฆ์ "+p.getPrinterName()+"์
๋๋ค.")
p.printText("We successfully arrived the moon.")
- ๋ณด๋ฉด, ๋ณด์คํ ํฌ, ๋จธํ๋ฆฌ๋ → ๋๋ฆฌ์ธ์ด ๊ฐ๋ณ๊ฒ ์ผ์ ์ฒ๋ฆฌํฉ๋๋ค.
- Printer์ ์ธ์คํด์ค (๋จธํ๋ฆฌ)๋ฅผ ์์ฑ์ค์ธ ๊ณผ์ ์ → ๋ณธ์ธ์ด ์ฒ๋ฆฌํฉ๋๋ค. (๋ถํ ๊ณผ์ ์ ๋๋ค)
Proxy Pattern - Example.2 : Sequence Diagram
Proxy๋ฅผ ์ฌ์ฉํด์ ์๋ ์ฌ๋ฆฌ๊ธฐ
- Proxy๋ ๊ฐ๋ฅํ ์ผ๋ง ์ฒ๋ฆฌํ์ง๋ง, ์ค์ ๋ก printํ ๋ ๊น์ง ๋ฌด๊ฑฐ์ด ์ฒ๋ฆฌ๋ฅผ ์ง์ฐ์ํฌ ์ ์์ต๋๋ค.
- ๊ฐ๋ น ๋๊ท๋ชจ ์์คํ ์ ์๊ฐํด๋ณด๋ฉด, ๊ธฐ๋์์ ์์ ์ด์ฉํ์ง ์๋ ๊ธฐ๋ฅ๊น์ง ์ ๋ถ ์ด๊ธฐํํ๋ฉด, ์ดํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋์ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. → ์ด๊ฑด ์ฌ์ฉ์๋ค์ ๋ถ๋ง์ผ๋ก ์ด์ด์ง์๋ ์์ต๋๋ค.
- ๊ทธ๋์ ์ค์ ๋ก ์ฌ์ฉํ๋ ์์ , ๊ทธ ๋จ๊ณ๊ฐ ๋์์๋ ์ฒ์์ผ๋ก ์ด๊ธฐํ ํ๋ํธ์ด ์คํธ๋ ์ค๋ฅผ ์ค์ฌ์ค๋๋ค.
Proxy & Real ๋ถ๋ฆฌ ํ์?
- Printer ํด๋์ค ์์ ์ฒ์๋ถํฐ ์ง์ฐ ํ๊ฐ์ ๊ธฐ๋ฅ์ ๋ฃ์ ์๋ ์์ → But, Design pattern์ ๊ธฐ๋ฅ์ ์๋ฐฐ๋จ.
- ๊ทธ๋ฌ๋, ๋์ ๋ถ๋ฆฌํด์ ํ๋ก๊ทธ๋จ์ ๋ถํํ ํ์ฌ ๋ง๋ค๋ฉด, ๊ฐ๋ณ์ ์ผ๋ก ์์ ์ด ๊ฐ๋ฅํจ
ํฌ๊ณผ์ API
- PrinterProxy ํด๋์ค์ Printer ํด๋์ค๋ ๊ฐ์ Printable์ด๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ์์ต๋๋ค.
- Main ํด๋์ค๋ ์ค์ ๋ก ํธ์ถํ๋ ๊ณณ์ด PrintProxy ํด๋์ค์ด๋ , Printer ํด๋์ค์ด๋ ์๊ดํ์ง ์์ต๋๋ค.
- Printer๋ฅผ ์ง์ ์ด์ฉํด๋, ์ค๊ฐ์ PrinterProxy๊ฐ ๋ค์ด์๋ ๋ฌธ์ ์์ด ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค๋ ์๋ฏธ์ ๋๋ค.
- ์ด๋ฌํ ๊ฒฝ์ฐ PrinterProxy ํด๋์ค๋ ํฌ๊ณผ์ ์ด๋ผ๊ณ ๋งํ ์ ์์ต๋๋ค.
HTTP Proxy
- Proxy๋ผ๊ณ ํ๋ฉด HTTP Proxy๊ฐ ๋จผ์ ๋ ์ค๋ฆ ๋๋ค.
- HTTP Proxy๋ HTTP ์๋ฒ, ํด๋ผ์ด์ธํธ ์ฌ์ด์์ ์นํ์ด์ง์ cashing์ ์คํํ๋ ์ํํธ์จ์ด์ด๋ฉฐ ์ด๊ฒ๋ Proxyํจํด์ ์ ์ฉํด์ ์๊ฐํ ์ ์์ต๋๋ค.
- HTTP Proxy๋ ๋ง์ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์๋ ์ผ๋ก๋ก ํ์ด์ง์ cashing์ ๋ํ์ฌ ์ค๋ช ์ ํ๋ฉด, ์น๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ค ์นํ์ด์ง๋ฅผ ํ์ํ ๋, ์ผ์ผ์ด ์๊ฒฉ์ง์ ์๋ ์น ์๋ฒ์ ์์ธ์คํด์ ํ์ด์ง๋ฅผ ์ทจ๋ํ๋ ๊ฑฐ์ด ์๋, HTTP Proxy๊ฐ ์บ์ฌํด์ ์ด๋ค ์นํ์ด์ง๋ฅผ ๋์ ํด์ ์ทจ๋ํ๊ฒ ๋๋ฉฐ, ์ต์ ์ ๋ณด๊ฐ ํ์ํ๊ฑฐ๋ ํ์ด์ง์ ์ ํจ๊ธฐ๊ฐ์ด ์ง๋ฌ์๋ ์น ์๋ฒ์ ์น ํ์ด์ง๋ฅผ ๊ฐ์ง๋ฌ ๊ฐ๋๋ค.
ํ๋ก์ ํจํด - ์์ .2 : ์ํ์ค ๋ค์ด์ด๊ทธ๋จ
๋ฐ์ํ
'๐บ๏ธ Design Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Design Pattern] Decorator Pattern - ๋ฐ์ฝ๋ ์ดํฐ ํจํด (0) | 2024.06.05 |
---|---|
[Design Pattern] Adapter Pattern - ์ด๋ํฐ ํจํด (0) | 2024.05.27 |
[Design Pattern] Singleton Pattern - ์ฑ๊ธํค ํจํด & Metaclass (0) | 2024.05.21 |
[Design Pattern] Builder Pattern - ๋น๋ ํจํด (0) | 2024.05.21 |
[Design Pattern] Prototype Pattern - ํ๋กํ ํ์ ํจํด (0) | 2024.05.21 |