Skip to content

Latest commit

Β 

History

History
191 lines (147 loc) Β· 10.5 KB

mvc-python.md

File metadata and controls

191 lines (147 loc) Β· 10.5 KB

MVC (Model-View-Controller) λ””μžμΈ νŒ¨ν„΄

μž‘μ„±μž : μ •ν¬μž¬

λ³Έ μžλ£ŒλŠ” '파이썬 λ””μžμΈ νŒ¨ν„΄ 2/e (Chetan Giridhar)' 책을 ν† λŒ€λ‘œ μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ λͺ¨λ“  μ˜ˆμ‹œ μ½”λ“œμ—λŠ” μ €μžλ₯Ό ν‘œμ‹œν•˜λŠ” __author__ = 'Chetan' 이 ν¬ν•¨λ©λ‹ˆλ‹€.

Table of Contents

μ»΄νŒŒμš΄λ“œ νŒ¨ν„΄ κ°œμš”

μ†Œν”„νŠΈμ›¨μ–΄ κ°œλ°œμ—μ„œλŠ” ν•˜λ‚˜μ˜ λ””μžμΈ νŒ¨ν„΄λ§Œμ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³  μ—¬λŸ¬ 가지 νŒ¨ν„΄μ„ μ„žμ–΄ μ‚¬μš©ν•œλ‹€. 일반적으둜 μ—¬λŸ¬ νŒ¨ν„΄μ„ 합쳐 λͺ©μ μ„ λ‹¬μ„±ν•œλ‹€. GoF에 λ”°λ₯΄λ©΄ μ»΄νŒŒμš΄λ“œ νŒ¨ν„΄μ€ 2개 μ΄μƒμ˜ νŒ¨ν„΄μ„ 합쳐 문제λ₯Ό ν•΄κ²°ν•˜λŠ” νŒ¨ν„΄μ΄λ‹€. ν•˜μ§€λ§Œ μ»΄νŒŒμš΄λ“œ νŒ¨ν„΄μ€ λ‹¨μˆœνžˆ μ—¬λŸ¬ νŒ¨ν„΄μ˜ 쑰합이 μ•„λ‹Œ 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 독립적인 μ†”λ£¨μ…˜μ΄λ‹€.


MVC νŒ¨ν„΄

MVC νŒ¨ν„΄μ€ μœ μ € μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•  수 μžˆλŠ” μœ μ§€λ³΄μˆ˜κ°€ μš©μ΄ν•œ λ””μžμΈ νŒ¨ν„΄μ΄λ‹€. MVC νŒ¨ν„΄μ€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λͺ¨λΈκ³Ό λ·°, 컨트둀러둜 λ‚˜λˆ„μ–΄ κ΅¬μ„±ν•œλ‹€. 각 νŒŒνŠΈλŠ” 맞물렀 있으며 μš”μ²­μ˜ μ²˜λ¦¬μ™€ ν‘œν˜„μ„ λΆ„λ¦¬ν•œλ‹€.

MVC νŒ¨ν„΄μ˜ 원리

λͺ¨λΈμ€ 데이터와 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ μ²˜λ¦¬ν•˜κ³  λ·°λŠ” λ°μ΄ν„°μ˜ μ‹œκ°μ  ν‘œν˜„μ„ λ‹΄λ‹Ήν•˜λ©° μ»¨νŠΈλ‘€λŸ¬λŠ” μ‚¬μš©μžμ˜ μš”μ²­μ— 따라 λͺ¨λΈκ³Ό λ·° μ‚¬μ΄μ—μ„œ μš”μ²­μ„ μ²˜λ¦¬ν•œλ‹€. 뷰와 μ»¨νŠΈλ‘€λŸ¬λŠ” λͺ¨λΈμ— μ˜μ‘΄ν•˜μ§€λ§Œ κ·Έ λ°˜λŒ€λŠ” μ•„λ‹ˆλ‹€. μ‚¬μš©μžκ°€ 데이터λ₯Ό 직접 μš”μ²­ν•˜λŠ” ꡬ쑰이기 λ•Œλ¬Έμ΄λ‹€. 이와 같은 λͺ¨λΈμ˜ 독립성이 MVC νŒ¨ν„΄μ˜ μ€‘μš”ν•œ 뢀뢄이닀.

MVC νŒ¨ν„΄μ˜ μ „ν˜•μ μΈ μ˜ˆμ‹œ, μ›Ήμ‚¬μ΄νŠΈ 둜직

  1. μ‚¬μš©μžλŠ” λ·°λ₯Ό 톡해 μš”μ²­μ„ 보낸닀. λ·°λŠ” μ‚¬μš©μžμ—κ²Œ λ³΄μ—¬μ§€λŠ” μ›Ήμ‚¬μ΄νŠΈλ‹€. 뷰에 μžˆλŠ” λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ λ·°λŠ” μ»¨νŠΈλ‘€λŸ¬μ—κ²Œ μš”μ²­μ„ μ „λ‹¬ν•œλ‹€.
  2. μ»¨νŠΈλ‘€λŸ¬λŠ” 뷰에 전달받은 인풋을 λͺ¨λΈλ‘œ 보낸닀. λͺ¨λΈμ€ μš”μ²­μ— λ§žλŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.
  3. μ»¨νŠΈλ‘€λŸ¬λŠ” μ‚¬μš©μžμ˜ μš”μ²­μ— 따라 λ²„νŠΌ ꡐ체 및 UI μΆ”κ°€ 등을 뷰에 μ§€μ‹œν•  수 μžˆλ‹€.
  4. λͺ¨λΈμ€ 뷰에 μƒνƒœ 변경을 μ•Œλ¦°λ‹€. λ‚΄λΆ€ 둜직 λ˜λŠ” λ²„νŠΌ 클릭 λ“±μ˜ μ™ΈλΆ€ νŠΈλ¦¬κ±°μ— μ˜ν•œ μƒνƒœ 변경이닀.
  5. λ·°λŠ” λͺ¨λΈμ΄ μ „λ‹¬ν•œ μƒνƒœλ₯Ό 좜λ ₯ν•œλ‹€. 예λ₯Ό λ“€μ–΄ μ‚¬μš©μžκ°€ μ›Ήμ‚¬μ΄νŠΈμ— λ‘œκ·ΈμΈν•˜λ©΄ λŒ€μ‹œλ³΄λ“œλ₯Ό ν‘œμ‹œν•œλ‹€. λŒ€μ‹œλ³΄λ“œμ˜ μ„ΈλΆ€ λ‚΄μš©μ€ λͺ¨λΈμ΄ 뷰에 μ „λ‹¬ν•œλ‹€.

MVC νŒ¨ν„΄μ˜ 4가지 κ΅¬μ„±μš”μ†Œ

  1. λͺ¨λΈ : 데이터λ₯Ό μ €μž₯ν•˜κ³  μ‘°μž‘ν•˜λŠ” 클래슀
  2. λ·° : μœ μ € μΈν„°νŽ˜μ΄μŠ€μ™€ λ°μ΄ν„°μ˜ μ‹œκ°μ  ν‘œν˜„μ„ λ‹΄λ‹Ήν•˜λŠ” 클래슀
  3. 컨트둀러 : λͺ¨λΈκ³Ό λ·°λ₯Ό μ—°κ²°ν•˜λŠ” 클래슀
  4. ν΄λΌμ΄μ–ΈνŠΈ : λͺ©μ μ— 따라 정보λ₯Ό μš”μ²­ν•˜λŠ” 클래슀

개발 κ΄€μ μ—μ„œ λ³Έ MVC νŒ¨ν„΄μ˜ 메인 클래슀

  1. Model : λ°μ΄ν„°μ˜ 생성과 μˆ˜μ •, μ†Œλ©Έ λ“± 데이터에 κ΄€ν•œ λͺ¨λ“  μž‘μ—…μ„ μ •μ˜ν•˜κ³  데이터λ₯Ό μ‚¬μš©ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό μ œκ³΅ν•œλ‹€.
  2. View : μœ μ € μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ‹΄λ‹Ήν•œλ‹€. μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— ν•„μš”ν•œ μ›Ήμ΄λ‚˜ GUIλ₯Ό μƒμ„±ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό ν¬ν•¨ν•œλ‹€. μ „λ‹¬λ°›λŠ” 데이터λ₯Ό μ‹œκ°μ μœΌλ‘œ ν‘œν˜„ν•˜λŠ” κΈ°λŠ₯ μ™Έ κ°œλ³„μ μΈ λ‘œμ§μ„ ν¬ν•¨ν•˜μ§€ μ•Šμ•„μ•Ό ν•œλ‹€.
  3. Controller : 데이터λ₯Ό λ°›κ³  μ „λ‹¬ν•œλ‹€. μš”μ²­μ„ λΌμš°νŒ…ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό ν¬ν•¨ν•œλ‹€.

MVC νŒ¨ν„΄μ˜ λͺ©μ 

  1. 데이터 μ‘°μž‘κ³Ό ν‘œν˜„μ˜ 뢄리
  2. μ‰¬μš΄ μœ μ§€λ³΄μˆ˜μ™€ κ΅¬ν˜„
  3. μœ μ—°ν•œ 데이터 μ €μž₯κ³Ό ν‘œν˜„ λ°©μ‹μ˜ μˆ˜μ •. μ„œλ‘œ λ…λ¦½μ μ΄λ―€λ‘œ μ‰½κ²Œ μˆ˜μ •ν•  수 μžˆλ‹€.

MVC κ΅¬μ„±μš”μ†Œ 이해

λͺ¨λΈ - μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λ‡Œ

  • λͺ¨λΈμ€ 뷰와 μ»¨νŠΈλ‘€λŸ¬μ™€λŠ” 독립적인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 일뢀이닀. 뷰와 μ»¨νŠΈλ‘€λŸ¬λŠ” λͺ¨λΈμ— μ˜μ‘΄μ μ΄λ‹€.
  • λͺ¨λΈμ€ μ‚¬μš©μžκ°€ μš”μ²­ν•œ 데이터λ₯Ό μ œκ³΅ν•œλ‹€. 일반적으둜 λͺ¨λΈμ€ 데이터λ₯Ό μ €μž₯ν•˜κ³  λ°˜ν™˜ν•˜λŠ” λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ΄λ‹€. λͺ¨λΈμ€ μƒνƒœ 정보와 μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό ν¬ν•¨ν•˜μ§€λ§Œ 데이터가 μ‚¬μš©μžμ—κ²Œ μ–΄λ–€ ν˜•νƒœλ‘œ λ³΄μ—¬μ§€λŠ”μ§€ μ•Œμ§€ λͺ»ν•œλ‹€.
  • λͺ¨λΈμ€ λ°˜λ“œμ‹œ μ—¬λŸ¬ μž‘μ—… κ°„ 일관성을 μœ μ§€ν•΄μ•Ό ν•œλ‹€. 그렇지 μ•ŠμœΌλ©΄ μ‚¬μš©μžλŠ” 일관성 μ—†λŠ” 였래된 데이터λ₯Ό 전달 λ°›λŠ”λ‹€.
  • λͺ¨λΈμ€ μ™„μ „νžˆ λ…λ¦½μ μ΄λ―€λ‘œ κ°œλ°œμžλŠ” 뷰와 상관없이 λͺ¨λΈ μœ μ§€λ³΄μˆ˜μ— 집쀑할 수 μžˆλ‹€.

λ·° - μ™Έλͺ¨

  • λ·°λŠ” μ‚¬μš©μžκ°€ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ 보게 λ˜λŠ” λ°μ΄ν„°μ˜ μ‹œκ°μ  ν‘œν˜„μ΄λ‹€. λ·°λ₯Ό λ…λ¦½μ μœΌλ‘œ μž‘μ„±ν•  수 μžˆμœΌλ‚˜ λ³΅μž‘ν•œ λ‘œμ§μ„ ν¬ν•¨ν•˜λ©΄ μ•ˆλœλ‹€. λͺ¨λ“  λ‘œμ§μ€ μ»¨νŠΈλ‘€λŸ¬λ‚˜ λͺ¨λΈμ— ν¬ν•¨λ˜μ–΄μ•Ό ν•œλ‹€.
  • 특히 μš”μ¦˜μ²˜λŸΌ λ°μŠ€ν¬ν†±κ³Ό λͺ¨λ°”일 λ“±μ˜ μ—¬λŸ¬ ν”Œλž«νΌκ³Ό λ‹€μ–‘ν•œ ν™”λ©΄ 크기의 κΈ°κΈ°λ₯Ό λͺ¨λ‘ μ§€μ›ν•˜λ €λ©΄ λ·°λŠ” μ΅œλŒ€ν•œ μœ μ—°ν•΄μ•Ό ν•œλ‹€.
  • λ·°λŠ” λ°μ΄ν„°λ² μ΄μŠ€μ™€ 직접 ν†΅μ‹ ν•˜μ§€ μ•Šκ³  μ›ν•˜λŠ” 정보λ₯Ό μ–»κΈ° μœ„ν•΄ λͺ¨λΈμ— μ˜μ‘΄ν•΄μ•Ό ν•œλ‹€.

컨트둀러 - μ ‘μ°©μ œ

  • μ»¨νŠΈλ‘€λŸ¬λŠ” μ΄λ¦„μ—μ„œ μ§μž‘ν•  수 μžˆλ“―μ΄ μ‚¬μš©μžμ˜ 행동을 μ œμ–΄ν•œλ‹€. μ‚¬μš©μžκ°€ μΈν„°νŽ˜μ΄μŠ€ λ‚΄μ˜ νŠΉμ • μš”μ†Œλ₯Ό ν΄λ¦­ν•˜λ©΄ 행동(클릭 λ˜λŠ” ν„°μΉ˜)에 따라 μ»¨νŠΈλ‘€λŸ¬λŠ” λͺ¨λΈμ„ ν˜ΈμΆœν•΄ 데이터λ₯Ό 생성 λ˜λŠ” κ°±μ‹ , μ‚­μ œν•œλ‹€.
  • μ»¨νŠΈλ‘€λŸ¬λŠ” 뷰에 데이터λ₯Ό μ „λ‹¬ν•˜κ³  λ·°λŠ” ν•΄λ‹Ή 데이터λ₯Ό λ Œλ”λ§ν•΄ μ‚¬μš©μžμ—κ²Œ 보여쀀닀.
  • μ»¨νŠΈλ‘€λŸ¬λŠ” λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό 직접 ν˜ΈμΆœν•˜κ±°λ‚˜ 데이터λ₯Ό μ‹œκ°ν™”ν•˜μ§€ μ•ŠλŠ”λ‹€. μ»¨νŠΈλ‘€λŸ¬λŠ” λͺ¨λΈκ³Ό λ·° μ‚¬μ΄μ—μ„œ 얇은 μ ‘μ°©μ œ 역할을 ν•œλ‹€.

MVC νŒ¨ν„΄ μ˜ˆμ‹œ 1

이메일, SMS, μŒμ„± λ©”μ‹œμ§€λ₯Ό μ œκ³΅ν•˜λŠ” ν΄λΌμš°λ“œ μ„œλΉ„μŠ€

Python

__author__ = 'Chetan'
class Model(object):
    services = {
        'email': {'number': 1000, 'price': 2,},
        'sms': {'number': 1000, 'price': 10,},
        'voice': {'number': 1000, 'price': 15,},
    }

class View(object):
    def list_services(self, services):
        for svc in services:
            print(svc, ' ')

    def list_pricing(self, services):
        for svc in services:
            print("For" , Model.services[svc]['number'],
                    svc, "message you pay $",
                    Model.services[svc]['price'])

class Controller(object):
    def __init__(self):
        self.model = Model()
        self.view = View()

    def get_services(self):
        services = self.model.services.keys()
        return(self.view.list_services(services))

    def get_pricing(self):
        services = self.model.services.keys()
        return(self.view.list_pricing(services))

class Client(object):
    controller = Controller()
    print("Services Provided:")
    controller.get_services()

    print("Pricing for Services:")
    controller.get_pricing()

MVC νŒ¨ν„΄ μ˜ˆμ‹œ 2

λͺ¨λ“  클래슀λ₯Ό κ΅¬ν˜„ν•œ μ½”λ“œ μ˜ˆμ‹œ

Python

class Model(object):
    def logic(self):
        data = 'Got it!'
        print("Model: Crunching data as per business logic")
        return data

class View(object):
    def update(self, data):
        print("View: Updating the view with results: ", data)

class Controller(object):
    def __init__(self):
        self.model = Model()
        self.view = View()

    def interface(self):
        print("Controller: Relayed the Client asks")
        data = self.model.logic()
        self.view.update(data)

class Client(object):
    print("Client: asks for certain information")
    controller = Controller()
    controller.interface()

MVC νŒ¨ν„΄μ˜ μž₯점

  1. MVCλ₯Ό μ‚¬μš©ν•˜λ©΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λͺ¨λΈκ³Ό λ·°, 컨트둀러 총 3개의 파트둜 λ‚˜λˆŒ 수 μžˆλ‹€. 이 κ΅¬μ‘°λŠ” μœ μ§€λ³΄μˆ˜κ°€ 쉽고 μš”μ†Œ κ°„μ˜ 독립성이 λ†’μ•„μ Έ λ³΅μž‘μ„±μ΄ 쀄어든닀.
  2. λ°±μ—”λ“œ λ‘œμ§μ„ 거의 κ±΄λ“œλ¦¬μ§€ μ•Šκ³  λ…λ¦½μ μœΌλ‘œ ν”„λ‘ νŠΈ μ—”λ“œλ₯Ό μˆ˜μ •ν•  수 μžˆλ‹€.
  3. λͺ¨λΈμ΄λ‚˜ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§λ„ λ§ˆμ°¬κ°€μ§€λ‘œ 뷰와 상관없이 μˆ˜μ •λ  수 μžˆλ‹€.
  4. 컨트둀러 λ˜ν•œ 뷰와 λͺ¨λΈκ³ΌλŠ” λ…λ¦½μ μœΌλ‘œ μˆ˜μ •λ  수 μžˆλ‹€.
  5. ν”Œλž«νΌ κ°œλ°œμžμ™€ UI 개발자 같이 νŠΉμ • λΆ„μ•Όμ˜ 전문가듀이 λ…λ¦½μ μœΌλ‘œ 일할 수 μžˆλŠ” ν™˜κ²½μ„ μ œκ³΅ν•œλ‹€.

자주 λ¬»λŠ” 질문

  1. MVC도 ν•˜λ‚˜μ˜ νŒ¨ν„΄μΈλ° μ™œ μ»΄νŒŒμš΄λ“œ νŒ¨ν„΄μ΄λΌκ³  λΆˆλ¦¬λŠ”κ°€?

μ»΄νŒŒμš΄λ“œ νŒ¨ν„΄μ€ 더 큰 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ—¬λŸ¬ νŒ¨ν„΄μ„ ν•©μΉœ 것이닀. MVC νŒ¨ν„΄μ€ κ°€μž₯ 많이 μ“°μ΄λŠ” μ»΄νŒŒμš΄λ“œ νŒ¨ν„΄μ΄λ‹€. μ•ˆμ •μ μ΄λ©° 많이 쓰이기 λ•Œλ¬Έμ— κ°œλ³„μ μΈ νŒ¨ν„΄μ²˜λŸΌ μ·¨κΈ‰λœλ‹€.

MVCμ—λŠ” μ–΄λ–€ νŒ¨ν„΄λ“€μ΄ ν¬ν•¨λ˜μ–΄ μžˆλŠ”κ°€?


- μ˜΅μ €λ²„(Observer) νŒ¨ν„΄
Model 의 μƒνƒœκ°€ λ³€κ²½ λ˜μ—ˆμ„ λ•Œ Controller, ν˜Ήμ€ View μ—κ²Œ 이 사싀을 μ•Œλ¦¬λŠ”λ° μ‚¬μš©λœλ‹€.

- μ»΄ν¬μ§€νŠΈ(Composite) νŒ¨ν„΄
View λ₯Ό κ΅¬μ„±ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ“€μ€ 계측 ꡬ쑰λ₯Ό 이룬닀. (e.g. Java Swing 의 JFrame/JLabel λ“±, Android 의 View/ViewGroup, HTML 의 DOM)

- μŠ€νŠΈλž˜ν‹°μ§€(Strategy) νŒ¨ν„΄
Controller 의 핡심 κΈ°λŠ₯을 μΈν„°νŽ˜μ΄μŠ€λ‘œ λΆ„λ¦¬ν•˜μ—¬ View κ°€ 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 Controller λ₯Ό ꡬ성(Composition) ν•œλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— View λŠ” Controller λ₯Ό κ°ˆμ•„ 끼우며 κΈ°λŠ₯을 λ³€κ²½ν•  수 μžˆλ‹€.

- λ˜ν•œ, ν•„μš”μ— 따라 μ–΄λŒ‘ν„°(Adapter) νŒ¨ν„΄ 을 ν•¨κ»˜ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.

좜처 : Sungho's Blog

  1. MVC μ›Ήμ‚¬μ΄νŠΈμ—μ„œλ§Œ μ“°μ΄λŠ”κ°€?

그렇지 μ•Šλ‹€. μ›Ήμ‚¬μ΄νŠΈκ°€ MVCλ₯Ό μ„€λͺ…ν•˜κΈ° κ°€μž₯ 쒋은 μ˜ˆλ‹€. MVC νŒ¨ν„΄μ€ GUI기반 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄λ‚˜ ν”„λ‘œκ·Έλž¨ λ‚΄ μš”μ†Œ κ°„μ˜ 높은 독립성이 μš”κ΅¬λ˜λŠ” 경우 μ ν•©ν•˜λ‹€. λΈ”λ‘œκ·Έλ‚˜ μ˜ν™” λ°μ΄ν„°λ² μ΄μŠ€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜, λΉ„λ””μ˜€ 슀트리밍 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 등이 MVCκ°€ μ ν•©ν•œ μ „ν˜•μ μΈ μ˜ˆλ‹€. ν•˜μ§€λ§Œ MVCκ°€ 아무리 μ’‹λ‹€ 해도 λžœλ”© νŽ˜μ΄μ§€λ‚˜ λ§ˆμΌ€νŒ… μ½˜ν…μΈ , 단일 νŽ˜μ΄μ§€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 등에 μ“°λŠ” 것은 μ ν•©ν•˜μ§€ μ•Šλ‹€.

  1. μ—¬λŸ¬ 개의 뷰와 λͺ¨λΈμ„ μ‚¬μš©ν•΄λ„ λ˜λŠ”κ°€?

물둠이닀. μ—¬λŸ¬ λͺ¨λΈμ—μ„œ 데이터λ₯Ό μˆ˜μ§‘ν•΄ ν•œ 개의 뷰에 λ³΄μ—¬μ€˜μ•Ό ν•˜λŠ” κ²½μš°κ°€ 자주 μžˆλ‹€. μš”μ¦˜ μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” μΌλŒ€μΌ 맀핑을 μ“°λŠ” κ²½μš°κ°€ ν”μΉ˜ μ•Šλ‹€.