U E D R , A S I H C RSS

Gof/Facade

From GoF.


1. FACADE

1.1. Intent

μ„œλΈŒμ‹œμŠ€ν…œμ˜ μΈν„°νŽ˜μ΄μŠ€μ§‘ν•©μ— μΌκ΄€λœ μΈν„°νŽ˜μ΄μŠ€λΌ μ œκ³΅ν•œλ‹€. FacadeλŠ” κ³ κΈ‰λ ˆλ²¨μ˜ μΈν„°νŽ˜μ΄μŠ€λΌ μ •μ˜ν•¨μœΌλ‘œμ„œ μ„œλΈŒμ‹œμŠ€ν…œμ„ 더 μ‚¬μš©ν•˜κΈ° μ‰½κ²Œ ν•΄μ€λ‹€.

1.2. Motivation

μ„œλΈŒμ‹œμŠ€ν…œμ„ κ΅¬μΆ•ν•˜λŠ” 것은 λ³΅μž‘ν•¨μ„ μ„μ΄λŠ”λ° 도움을 μ€λ‹€. 일반적인 λ””μžμΈμ˜ λͺ©μ μ€ 각 μ„œλΈŒμ‹œμŠ€ν…œκ°„μ˜ 톡신과 μ˜μ‘΄μ„±μ„ μ΅œμ†Œν™”μ‹œν‚€λŠ” 것이닀. 이 λͺ©μ μ„ μ„±μ·¨ν•˜κΈ° μœ„ν•œ ν•œκ°€μ§€ λ°©λ²•μœΌλ‘œλŠ” λ‹¨μΌν•˜κ³  λ‹¨μˆœν•œ μΈν„°νŽ˜μ΄μŠ€λΌ μ œκ³΅ν•˜λŠ” facade objectλΌ λ„μž…ν•˜λŠ” 것이닀.


μ˜ˆλΌ λ“€κΈ° μœ„ν•΄, μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—κ²Œ 컴파일러 μ„œλΈŒμ‹œμŠ€ν…œμ„ μ œκ³΅ν•΄μ£ΌλŠ” ν”„λ‘œκ·Έλž˜λ° ν™˜κ²½μ΄ μžˆλ‹€κ³  ν•˜μž. 이 μ„œλΈŒμ‹œμŠ€ν…œμ€ μ»΄νŒŒμΌλŸ¬λΌ κ΅¬ν˜„ν•˜λŠ” Scanner, Parser, ProgramNode, BytecodeStream, 그리고 ProgramNodeBuilder ν΄λž˜μŠ€λΌ ν¬ν•¨ν•˜κ³  μžˆλ‹€. λͺ‡λͺ‡ νŠΉμˆ˜ν™”λœ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μ΄λŸ¬ν•œ ν΄λž˜μŠ€λ“€μ„ μ§μ ‘μ μœΌλ‘œ μ ‘κ·Όν•  ν•„μš”κ°€ μžˆμ„ 것이닀. ν•˜μ§€λ§Œ, λŒ€λΆ€λΆ„μ˜ 컴파일러 μ‹œμŠ€ν…œμ„ μ΄μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλ“€μ€ 일반적으둜 ꡬ문뢄석(Parsing)μ΄λ‚˜ μ½”λ“œ λ³€ν™˜ (Code generation) 의 세뢀적인 뢀뢄에 λŒ€ν•΄ μ‹ κ²½μ“Έ ν•„μš”κ°€ μ—†λ‹€.(그듀은 단지 μ•½κ°„μ˜ μ½”λ“œλΌ μ»΄νŒŒμΌν•˜κΈ° 원할뿐이지 λ‹€λ₯Έ κ°•λ ₯ν•œ κΈ°λŠ₯을 μ•Œ ν•„μš”κ°€ μ—†λ‹€.) κ·ΈλŸ¬ν•œ ν΄λΌμ΄μ–ΈνŠΈλ“€μ—κ²ŒλŠ” 컴파일러 μ„œλΈŒμ‹œμŠ€ν…œμ˜ κ°•λ ₯ν•˜μ§€λ§Œ μ €κΈ‰λ ˆλ²¨μΈ μΈν„°νŽ˜μ΄μŠ€λŠ” 단지 κ·Έλ“€μ˜ μž‘μ—…μ„ λ³΅μž‘ν•˜κ²Œ λ§Œλ“€ 뿐이닀.

μ΄λŸ¬ν•œ ν΄λž˜μŠ€λ“€λ‘œλΆ€ν„° ν΄λΌμ΄μ–ΈνŠΈλ“€μ„ λ³΄ν˜Έν•  수 μžˆλŠ” κ³ κΈ‰λ ˆλ²¨μ˜ μΈν„°νŽ˜μ΄μŠ€λΌ μ œκ³΅ν•˜κΈ° μœ„ν•΄ 컴파일러 μ„œλΈŒμ‹œμŠ€ν…œμ€ facade λ‘œμ„œ Compiler classλΌ ν¬ν•¨ν•œλ‹€. μ΄λŸ¬ν•œ ν΄λž˜μŠ€λŠ” 컴파일러의 각 κΈ°λŠ₯성듀에 λŒ€ν•œ λ‹¨μΌν•œ μΈν„°νŽ˜μ΄μŠ€λΌ μ •μ˜ν•œλ‹€. Compiler classλŠ” facade (μ›λž˜μ˜ 단어 λœ»μ€ 건물의 μ „λ©΄. μ™Έκ΄€, 겉보기..) λ‘œμ„œ μž‘μš©ν•œλ‹€. Compiler classλŠ” ν΄λΌμ΄μ–ΈνŠΈλ“€μ—κ²Œ 컴파일러 μ„œλΈŒμ‹œμŠ€ν…œμ— λŒ€ν•œ λ‹¨μΌν•˜κ³  λ‹¨μˆœν•œ μΈν„°νŽ˜μ΄μŠ€λΌ μ œκ³΅ν•œλ‹€. Compiler classλŠ” 컴파일러의 각 κΈ°λŠ₯듀을 κ΅¬ν˜„ν•œ ν΄λž˜μŠ€λ“€μ„ μ™„λ²½ν•˜κ²Œ μ€νμ‹œν‚€μ§€ μ•Šκ³ , ν•˜λ‚˜μ˜ ν΄λž˜μŠ€μ— ν¬ν•¨μ‹œμΌœμ„œ 뢙인닀. 컴파일러 facade λŠ”μ €κΈ‰λ ˆλ²¨μ˜ κΈ°λŠ₯λ“€μ˜ 은폐없이 λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž˜λ¨Έλ“€μ—κ²Œ νŽΈλ¦¬μ„±μ„ μ œκ³΅ν•œλ‹€.


1.3. Applicabilty

μ΄λŸ΄λ•Œ Facade Pattern을 μ‚¬μš©ν•˜λΌ.
  • λ³΅μž‘ν•œ μ„œλΈŒ μ‹œμŠ€ν…œμ— λŒ€ν•΄ λ‹¨μˆœν•œ μΈν„°νŽ˜μ΄μŠ€λΌ μ œκ³΅ν•˜κΈ° μ›ν• λ•Œ. μ„œλΈŒμ‹œμŠ€ν…œμ€ μ’…μ’… μ‹œμŠ€ν…œλ“€μ΄ λ°œμ „λ˜μ–΄λ‚˜κ°€λ©΄μ„œ λ”μš± λ³΅μž‘μ„±μ„ λ„κ²Œ λœλ‹€. λŒ€λΆ€λΆ„μ˜ νŒ¨ν„΄λ“€μ€ νŒ¨ν„΄μ΄ 적용된 결과둜 많고 μž‘μ€ ν΄λž˜μŠ€λ“€μ΄ 되게 ν•œλ‹€. νŒ¨ν„΄μ˜ μ μš©μ€ μ„œλΈŒμ‹œμŠ€ν…œλ“€μ΄ 더 μž¬μ‚¬μš©κ°€λŠ₯ν•˜κ³  μ»€μŠ€ν„°λ§ˆμ΄μ¦ˆν•˜κΈ° μ‰½κ²Œ ν•˜μ§€λ§Œ, μ»€μŠ€ν„°λ§ˆμ΄μ¦ˆν•  ν•„μš”κ°€ μ—†λŠ” ν΄λΌμ΄μ–ΈνŠΈλ“€μ΄ μ‚¬μš©ν•˜κΈ° μ–΄λ ΅κ²Œ λ§Œλ“ λ‹€. FacadeλŠ” μ„œλΈŒμ‹œμŠ€ν…œμ— λŒ€ν•œ λ‹¨μˆœν•˜κ³  기본적인 μ‹œκ°μ„ μ œκ³΅ν•œλ‹€. μ΄λŸ¬ν•œ μ‹œκ°μ€ λŒ€λΆ€λΆ„μ˜ ν΄λΌμ΄μ–ΈνŠΈλ“€μ—κ²Œ μΆ©λΆ„ν•˜λ‹€. μ»€μŠ€ν„°λ§ˆμ΄μ¦ˆκ°€ ν•„μš”ν•œ ν΄λΌμ΄μ–ΈνŠΈλ“€μ—κ²Œλ§Œμ΄ facadeλΌ λ„˜μ–΄μ„œ λ³Ό ν•„μš”κ°€ μžˆλŠ” 것이닀.
  • ν΄λΌμ΄μ–ΈνŠΈλ“€κ³Ό 좔상 ν΄λž˜μŠ€λ“€μ˜ κ΅¬ν˜„ μ‚¬μ΄μ—λŠ” λ§Žμ€ μ˜μ‘΄μ„±μ΄ μžˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλΈŒμ‹œμŠ€ν…œ μ‚¬μ΄λΌ λΆ„λ¦¬μ‹œν‚€κΈ° μœ„ν•΄ facadeλΌ λ„μž…ν•˜λΌ. κ·ΈλŸ¬ν•¨μœΌλ‘œμ„œ μ„œλΈŒν΄λž˜μŠ€μ˜ 독립성과 PortabilityλΌ μ¦μ§„μ‹œν‚¨λ‹€.
  • μ„œλΈŒμ‹œμŠ€ν…œμ— 계측을 두고 싢을 λ•Œ. 각 μ„œλΈŒμ‹œμŠ€ν…œ 레벨의 entry pointλΌ μ •μ˜ν•˜κΈ° μœ„ν•΄ facadeλΌ μ‚¬μš©ν•˜λΌ. 만일 각 μ„œλΈŒμ‹œμŠ€ν…œλ“€μ΄ μ„œλ‘œ 의쑴적이라면 μ„œλΈŒμ‹œμŠ€ν…œλ“€κ°„μ˜ λŒ€ν™”λΌ κ° μ‹œμŠ€ν…œκ°„μ˜ facade둜 단일화 μ‹œν‚΄μœΌλ‘œμ„œ κ·Έ μ˜μ‘΄μ„±μ„ λ‹¨μˆœν™”μ‹œν‚¬ 수 μžˆλ‹€.



1.4. Participant

Facade (Compiler)
- 각 μ„œλΈŒμ‹œμŠ€ν…œ ν΄λž˜μŠ€λŠ” 각 μš”μ²­μ— λŒ€ν•œ μ±…μž„μ΄ μžˆλ‹€.
- ν΄λΌμ΄μ–ΈνŠΈμ˜ μš”μ²­μ„ μ ν•©ν•œ μ„œλΈŒμ‹œμŠ€ν…œ κ°μ²΄μ—κ²Œ μœ„μž„ν•œλ‹€.
subsystem classes (Scanner, Parser, ProgramNode, etc.)
- μ„œλΈŒμ‹œμŠ€ν…œ κΈ°λŠ₯듀이 κ΅¬ν˜„λ˜μ–΄μžˆλ‹€.
- Facade 객체에 μ˜ν•΄ μ •μ˜λœ μž‘μ—…μ„ μ²˜λ¦¬ν•œλ‹€.
- facade 에 λŒ€ν•œ 정보가 ν•„μš”μ—†λ‹€. facade object에 λŒ€ν•œ referenceλΌ κ°€μ§€κ³  μžˆμ„ ν•„μš”κ°€ μ—†λ‹€.

1.5. Collaborations

  • ν΄λΌμ΄μ–ΈνŠΈλŠ” Facadeμ—κ²Œ μš”μ²­μ„ λ³΄λƒ„μœΌλ‘œμ„œ μ„œλΈŒμ‹œμŠ€ν…œκ³Ό λŒ€ν™”ν•œλ‹€. Facade κ°μ²΄λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ μš”μ²­μ„ μ ν•©ν•œ μ„œλΈŒμ‹œμŠ€ν…œ κ°μ²΄μ—κ²Œ λ„˜κΈ΄λ‹€. 비둝 μ„œλΈŒμ‹œμŠ€ν…œ 객체가 μ‹€μ œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜μ§€λ§Œ, facade λŠ” facade 의 μΈνΌνŽ˜μ΄μŠ€λΌ μ„œλΈŒμ‹œμŠ€ν…œμ˜ μΈν„°νŽ˜μ΄μŠ€λ‘œ λ²ˆμ—­ν•˜κΈ° μœ„ν•œ 고유의 μž‘μ—…μ„ ν•΄μ•Ό ν•  것이닀.
    facade λΌ μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλŠ” 직접 μ„œλΈŒμ‹œμŠ€ν…œ 객체에 μ ‘κ·Όν•  ν•„μš”κ°€ μ—†λ‹€.

1.6. Consequences

Facade Pattern은 λ‹€μŒκ³Ό 같은 이읡을 μ œκ³΅ν•΄μ€λ‹€.
  1. μ„œλΈŒμ‹œμŠ€ν…œ μ»΄ν¬λ„ŒνŠΈλ‘œλΆ€ν„° ν΄λΌμ΄μ–ΈνŠΈλ“€μ„ λ³΄ν˜Έν•œλ‹€. κ·ΈλŸ¬ν•¨μœΌλ‘œμ„œ ν΄λΌμ΄μ–ΈνŠΈκ°€ λ‹€λ£¨λŠ” 객체의 μˆ˜λΌ μ„이고, μ„œλΈŒμ‹œμŠ€ν…œμ„ μ΄μš©ν•˜κΈ° μ‰½κ²Œ ν•΄μ€λ‹€.
  2. μ„œλΈŒμ‹œμŠ€ν…œκ³Ό ν΄λΌμ΄μ–ΈνŠΈ κ°„μ˜ μ—°κ²°κ΄€κ³„λΌ μ•½ν•˜κ²Œ ν•΄μ€λ‹€. μ’…μ’… μ„œλΈŒμ‹œμŠ€ν…œ μ»΄ν¬λ„ŒνŠΈλŠ” ν΄λΌμ΄μ–ΈνŠΈμ™€ κ°•ν•œ μ—°κ²°κ΄€κ³„λΌ κ°€μ§€κΈ°λ„ ν•œλ‹€. μ•½ν•œ μ—°κ²°κ΄€κ³„λŠ” ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 영ν–₯을 λΈμΉ˜μ§€ μ•ŠμœΌλ©΄μ„œ μ„œλΈŒμ‹œμŠ€ν…œμ˜ μ»΄ν¬λ„ŒνŠΈλ“€μ„ λ‹€μ–‘ν•˜κ²Œ λ§Œλ“€μ–΄μ€λ‹€. Facade λŠ” μ‹œμŠ€ν…œκ³Ό κ°μ²΄κ°„μ˜ μ˜μ‘΄μ„±μ„ 계측화 ν•˜λŠ”λ° 도움을 μ€λ‹€. FacadeλŠ” λ³΅μž‘ν•¨μ΄λ‚˜ μˆœν™˜μ˜μ‘΄μ„±μ„ μ—†μ• μ€λ‹€. 이것은 ν΄ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλΈŒμ‹œμŠ€ν…œμ΄ λΉ„μ˜μ‘΄μ μœΌλ‘œ κ΅¬ν˜„λ˜μ—ˆμ„λ•Œμ˜ κ°€μž₯ μ€‘μš”ν•œ 결과일 것이닀.
  3. κ·ΈλŸ¬ν•˜λ©΄μ„œλ„ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μ—¬μ „νžˆ μ„œμŠ€μ‹œμŠ€ν…œ ν΄λž˜μŠ€λ“€μ„ μ‚¬μš©ν•  방법을 μ œκ³΅ν•œλ‹€. μ‚¬μš©μ˜ νŽΈλ¦¬μ„±κ³Ό μΌλ°˜μ„±μ„ 선택할 수 μžˆλ‹€.

1.7. Implementation

facadeλΌ κ΅¬ν˜„ν•  λ•Œ λ‹€μŒκ³Ό 같은 issueλΌ μƒκ°ν•˜λΌ.
  1. ν΄λΌμ΄μ–ΈνŠΈ-μ„œλΈŒμ‹œμŠ€ν…œ μ—°κ²°κ΄€κ³„λΌ μ„여라.
ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλΈŒμ‹œμŠ€ν…œκ°„μ˜ μ—°κ²°κ΄€κ³„λŠ” FacadeλΌ μΆ”μƒν΄λž˜μŠ€λ‘œ λ§Œλ“¬μœΌλ‘œμ„œ μ„일 수 μžˆλ‹€.
그러면 ν΄λΌμ΄μ–ΈνŠΈλŠ” 좔상 Facade class의 μΈν„°νŽ˜μ΄μŠ€λΌ ν†΅ν•΄ μ„œλΈŒμ‹œμŠ€ν…œκ³Ό λŒ€ν™”ν•  수 μžˆλ‹€. μ΄λŸ¬ν•œ μΆ”μƒν΄λž˜μŠ€μ™€μ˜ 연결은 ν΄λΌμ΄μ–ΈνŠΈκ°€ μ‚¬μš©ν•  μ„œλΈŒμ‹œμŠ€ν…œμ˜ κ΅¬ν˜„μ„ μ•Œμ•„μ•Ό ν•˜λŠ” ν•„μš”μ„±μ„ μ—†μ• μ€λ‹€.
μ„œλΈŒν΄λž˜μ‹±μ˜ λŒ€μ²΄λŠ” λ‹€λ₯Έ μ„œλΈŒμ‹œμŠ€ν…œ κ°μ²΄λΌ κ°€μ§„ Facade 객체둜 μ„μ •ν•˜λŠ” 것이닀. facadeλΌ μ»€μŠ€ν„°λ§ˆμ΄μ¦ˆν•˜λ €λ©΄ λ‹¨μˆœνžˆ μ„œλΈŒμ‹œμŠ€ν…œ κ°μ²΄λΌ λ‹€λ₯Έ 객체둜 κ΅ν™˜ν•œλ‹€.

2. public vs private μ„œλΈŒμ‹œμŠ€ν…œ 클래슀.
μ„œλΈŒμ‹œμŠ€ν…œμ€ μΈν„°νŽ˜μ΄μŠ€λΌ κ°€μ§„λ‹€λŠ” 점과 λ¬΄μ—‡μΈκ°€λΌ (ν΄λž˜μŠ€λŠ” state와 operation을 μΊ‘μŠν™”ν•˜λŠ” 반면, μ„œλΈŒμ‹œμŠ€ν…œμ€ classesλΌ μΊ‘μŠν™”ν•œλ‹€.) μΊ‘μŠν™”ν•œλ‹€λŠ” μ μ—μ„œ class 와 λΉ„μŠ·ν•˜λ‹€. class μ—μ„œ public κ³Ό private interfaceλΌ μƒκ°ν•˜λ“이 μš°λ¦¬λŠ” μ„œλΈŒμ‹œμŠ€ν…œμ—μ„œ public κ³Ό private interface 에 λŒ€ν•΄ 생각할 수 μžˆλ‹€.

μ„œλΈŒμ‹œμŠ€ν…œμœΌλ‘œμ˜ public interfaceλŠ” λͺ¨λ“  ν΄λΌμ΄μ–ΈνŠΈλ“€μ΄ 접속가λŠ₯ν•œ ν΄λž˜μŠ€λ“€λ‘œ κ΅¬μ„±λ˜λ©°. μ΄λ•Œ μ„œλΈŒμ‹œμŠ€ν…œμœΌλ‘œμ˜ private interfaceλŠ” 단지 μ„œλΈŒμ‹œμŠ€ν…œμ˜ ν™•μž₯μžλ“€μ„ μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€μ΄λ‹€. λ”°λΌμ„œ facade classλŠ” public interface의 일뢀이닀. ν•˜μ§€λ§Œ, μœ μΌν•œ 일뢀인 것은 μ•„λ‹ˆλ‹€. λ‹€λ₯Έ μ„œλΈŒμ‹œμŠ€ν…œ ν΄λž˜μŠ€λ“€ μ—­μ‹œ λŒ€κ²Œ public interface이닀. μ˜ˆλΌ λ“€μžλ©΄, 컴파일러 μ„œλΈŒμ‹œμŠ€ν…œμ˜ Parser classλ‚˜ Scanner class듀은 public interface의 일뢀이닀.
μ„œλΈŒμ‹œμŠ€ν…œ ν΄λž˜μŠ€λΌ private 둜 λ§Œλ“œλŠ” 것은 μœ μš©ν•˜μ§€λ§Œ, μΌλΆ€μ˜ OOP Languageκ°€ μ§€μ›ν•œλ‹€. C++κ³Ό Smalltalk λŠ” μ „ν†΅μ μœΌλ‘œ class에 λŒ€ν•œ namespaceλΌ globalν•˜κ²Œ 가진닀. ν•˜μ§€λ§Œ μ΅œκ·Όμ— C++ ν‘œμ€νšŒμ˜μ—μ„œ namespaceκ°€ μΆ”κ°€λ¨μœΌλ‘œμ„œ Str94, public μ„œλΈŒμ‹œμŠ€ν…œ ν΄λž˜μŠ€λΌ λ…ΈμΆœμ‹œν‚¬ 수 있게 λ˜μ—ˆλ‹€.Str94 (좩돌의 μ—¬μ§€λΌ μ„μ˜€λ‹€λŠ” 편이 λ§žμ„λ“..)

Sample Code
자, Compiler μ„œλΈŒμ‹œμŠ€ν…œμ— μ–΄λ–»κ²Œ facadeκ°€ μž…ν˜€μ§€λŠ”μ§€ μžμ„Ένžˆ 보도둝 ν•˜μž.

Compiler μ„œλΈŒμ‹œμŠ€ν…œμ€ BytecodeStream ν΄λž˜μŠ€λΌ μ •μ˜ν•œλ‹€. 이 ν΄λž˜μŠ€λŠ” Bytecode 객체의 μŠ€νŠΈλ¦ΌλΆ€λΌ κ΅¬ν˜„ν•œλ‹€. Bytecode κ°μ²΄λŠ” λ¨Έμ‹ μ½”λ“œλΌ κ΅¬μ²΄ν™”ν•˜λŠ” bytecodeλΌ μΊ‘μŠν™”ν•œλ‹€. μ„œλΈŒμ‹œμŠ€ν…œμ€ λ˜ν•œ Token ν΄λž˜μŠ€λΌ μ •μ˜ν•˜λŠ”λ°, Token κ°μ²΄λŠ” ν”„λ‘œκ·Έλž¨ μ–Έμ–΄λ‚΄μ˜ token듀을 μΊ‘μŠν™”ν•œλ‹€.

Scanner ν΄λž˜μŠ€λŠ” character μŠ€νŠΈλ¦Όμ„ μ–»μ–΄μ„œ token의 μŠ€νŠΈλ¦Όμ„ λ§Œλ“ λ‹€.

class Scanner {
public:
	Scanner (istream&);
	virtual ~Scanner ();

	virtual Token& Scan ();
private:
	istream& _inputStream;
};


Parser ν΄λž˜μŠ€λŠ” Scanner의 token둜 parse treeλΌ κ΅¬μΆ•ν•˜κΈ° μœ„ν•΄ ProgramNodeBuilder λΌ μ‚¬μš©ν•œλ‹€.

 
class Parser {
public:
	Parser ();
	virtual ~Parser ();

	virtual void Parse (Scanner&, ProgramNodeBuilder &);
};

ParserλŠ” μ μ§„μ μœΌλ‘œ parse treeλΌ λ§Œλ“€κΈ° μœ„ν•΄ ProgramNodeBuilder λΌ ν˜ΈμΆœν•œλ‹€. 이 ν΄λž˜μŠ€λ“€μ€ Builder pattern에 따라 μƒν˜Έμž‘μš©ν•œλ‹€.

 
class ProgramNodeBuilder {
public:
	ProgramNodeBuilder ();

	virtual ProgramNode* NewVariable (
		const char* variableName
	) const;

	virtual ProgramNode* NewAssignment (
		ProgramNode* variable, ProgramNode* expression
	) const;

	virtual ProgramNode* NewRetrunStatement (
		ProgramNode* value
	) const;

	virtual ProgramNode* NewCondition (
		ProgramNode* condition,
		ProgramNode* truePart, ProgramNode* falsePart
	) const;

	// ...

	ProgramNode* GetRootNode ();

private:
	ProgramNode* _node;
};

parser treeλŠ” StatementNode, ExpressionNode와 같은 ProgramNode의 subclassλ“€μ˜ μΈμŠ€ν„΄μŠ€λ“€λ‘œ 이루어진닀. ProgramNode 계측 κ΅¬μ‘°λŠ” Composite Pattern의 μ˜ˆμ΄λ‹€. ProgramNodeλŠ” program node 와 program node의 children을 μ‘°μž‘ν•˜κΈ° μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€λΌ μ •μ˜ν•œλ‹€.

 
class ProgramNode {
public:
	// program node manipulation
	virtual void GetSourcePosition (int& line, int& index);
	// ...


	// child manipulation
	virtual void Add (ProgramNode*);
	virtual void Remove (ProgramNode*);
	// ...

	virtual void Traverse (CodeGenerator&);
protected:
	ProgramNode ();
};

Traverse operaton은 CodeGenerator κ°μ²΄λΌ μΈμžλ‘œ μ·¨ν•œλ‹€. ProgramNode subclass듀은 BytecodeStream에 μžˆλŠ” Bytecode객체듀을 machine code둜 λ³€ν™˜ν•˜κΈ° μœ„ν•΄ CodeGenerator κ°μ²΄λΌ μ‚¬μš©ν•œλ‹€. CodeGenerator ν΄λž˜λŠ” visitor이닀. (VisitorPattern을 μ°Έμ‘°ν•˜λΌ)

class CodeGenerator {
public:
	virtual void Visit (StatementNode*);
	virtual void Visit (ExpressionNode*);
	// ...
protected:
	CodeGenerator (BytecodeStream&);
protected:
	BytecodeStream& _output;
};

CodeGenerator λŠ” subclassλΌ κ°€μ§„λ‹€. 예λΌλ“€μ–΄ StackMachineCodeGenerator sk RISCCodeGenerator λ“±. 각각의 λ‹€λ₯Έ ν•˜λ“œμ›¨μ–΄ μ•„ν‚€ν…μ²˜μ— λŒ€ν•œ machine code둜 λ³€ν™˜ν•˜λŠ” subclassλΌ κ°€μ§ˆ 수 μžˆλ‹€.

ProgramNode의 각 subclass듀은 ProgramNode의 child인 ProgramNode κ°μ²΄λΌ ν˜ΈμΆœν•˜κΈ° μœ„ν•΄ Traverse operation을 κ΅¬ν˜„ν•œλ‹€. 맀번 각 childλŠ” childrenμ—κ²Œ 같은 일을 μž¬κ·€μ μœΌλ‘œ μˆ˜ν–‰ν•œλ‹€. μ˜ˆλΌ λ“€μ–΄, ExpressionNodeλŠ” TraverseλΌ λ‹€μŒκ³Ό 같이 μ •μ˜ν•œλ‹€.
void ExpressionNode::Traverse (CodeGenerator& cg) {
	cg.Visit (this);

	ListIterator <ProgramNode*> i (_children);

	for (i.First (); !i.IsDone (); i.Next ()) {
		i.CurrentItem ()->Traverse (cg);
	}
}

μš°λ¦¬κ°€ ν† λ‘ ν•΄μ˜¨ ν΄λž˜μŠ€λ“€μ€ 곧 Compiler μ„œλΈŒμ‹œμŠ€ν…œμ„ 이룰 것이닀. 자 이제 μš°λ¦¬λŠ” 이 λͺ¨λ“  쑰각듀을 ν•¨κ»˜ 묢은 facade 인 Compiler ν΄λž˜μŠ€λΌ μ†Œκ°œν•  것이닀. CompilerλŠ” μ†ŒμŠ€ 컴파일과 νŠΉμ • machine에 λŒ€ν•œ μ½”λ“œλ³€ν™˜κΈ°λŠ₯에 λŒ€ν•œ λ‹¨μˆœν•œ μΈν„°νŽ˜μ΄μŠ€λΌ μ œκ³΅ν•œλ‹€.

class Compiler {
public:
	Compiler ();

	virtual void Compile (istream&, BytecodeStream&);
};

void Compiler::Compile (
	istream& input, BytecodeStream& output
) {
	Scanner scanner (input);
	ProgramNodeBuilder builder;
	Parser parser;

	parser.Parse (scanner, builder);

	RISCCodeGenerator generator (output);
	ProgramNode* parseTree = builder.GetRootNode ();
	parseTree->Traverse (generator);
}

이 κ΅¬ν˜„μ—μ„œλŠ” μ‚¬μš©ν•˜λ €λŠ” code-generator의 ν˜•νƒœμ— λŒ€ν•΄μ„œ hard-codes (직접 νŠΉμ •ν˜•νƒœ 뢀뢄을 μΆ”μƒν™”μ‹œν‚€μ§€ μ•Šκ³  λ°”λ‘œ μž…λ ₯)λΌ ν–ˆλ‹€. κ·Έλ ‡κ²Œ ν•¨μœΌλ‘œμ„œ ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” λͺ©μ μ΄ λ˜λŠ” μ•„ν‚€ν…μ²˜λ‘œ κ΅¬μ²΄ν™”μ‹œν‚€λ„λ‘ μš”κ΅¬λ°›μ§€ μ•ŠλŠ”λ‹€. 만일 λͺ©μ μ΄ λ˜λŠ” μ•„ν‚€ν…μ²˜κ°€ 단 ν•˜λ‚˜λΌλ©΄ 그것은 μ•„λ§ˆ 이성적인 νŒλ‹¨μΌ 것이닀. 만일 κ·ΈλŸ¬ν•œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ μš°λ¦¬λŠ” Compiler 의 constructor 에 CodeGenerator λΌ μΈμžλ‘œ μΆ”κ°€ν•˜κΈ° 원할 것이닀. 그러면 ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” CompilerλΌ instanceν™” ν• λ•Œ μ‚¬μš©ν•  generatorλΌ κ΅¬μ²΄ν™”ν•  수 μžˆλ‹€. Compiler facadeλŠ” λ˜ν•œ Scannerλ‚˜ ProgramNodeBuilder λ“±μ˜ λ‹€λ₯Έ ν˜‘λ™ν•˜λŠ” μ„œλΈŒμ‹œμŠ€ν…œν΄λž˜μŠ€λΌ μΈμžν™”ν•  수 μžˆλ‹€. 그것은 μœ μ—°μ„±μ„ μ¦κ°€μ‹œν‚€μ§€λ§Œ, λ˜ν•œ 일반적인 μ‚¬μš©ν˜•νƒœμ— λŒ€ν•΄ μΈν„°νŽ˜μ΄μŠ€μ˜ λ‹¨μˆœν•¨μ„ μ œκ³΅ν•˜λŠ” Facade pattern의 μ˜μ˜λΌ λ–¨μ–΄λœ¨λ¦°λ‹€.

1.8. Known Uses

Sample Code의 compiler 의 μ˜ˆλŠ” ObjectWorksSmalltalk compiler systemμ—μ„œ μ˜κ°μ„ 얻은 것이닀.Par90
ET++ application framework WGM88 μ—μ„œ, application은 run-time μƒμ—μ„œ application의 객체듀을 μ‚΄ν•„ 수 수 μžˆλŠ” built-in browsing toolsλΌ κ°€μ§€κ³  μžˆλ‹€.μ΄λŸ¬ν•œ browsing toolsλŠ” "ProgrammingEnvironment'라 λΆˆλ¦¬λŠ” facade classλΌ κ°€μ§„ κ΅¬λΆ„λœ μ„œλΈŒμ‹œμŠ€ν…œμ— κ΅¬ν˜„λ˜μ–΄μžˆλ‹€. 이 facadeλŠ” browser에 μ ‘κ·Ό ν•˜κΈ° μœ„ν•œ InspectObjectλ‚˜ InspectClass같은 operation을 μ •μ˜ν•œλ‹€.
ET++ application은 λ˜ν•œ built-in browsing supportλΌ μ—†μ•¨μˆ˜λ„ μžˆλ‹€. μ΄λŸ¬ν•œ 경우 ProgrammingEnvironmentλŠ” 이 μš”μ²­μ— λŒ€ν•΄ null-operationμœΌλ‘œμ„œ κ΅¬ν˜„ν•œλ‹€. κ·ΈλŸ¬ν•œ null-operationλŠ” 아무 일도 ν•˜μ§€ μ•ŠλŠ”λ‹€. 단지 ETProgrammingEnvironment subclassλŠ” 각각 λŒ€μ‘ν•˜λŠ” browser에 ν‘œμ‹œν•΄μ£ΌλŠ” operation을 가지고 μ΄λŸ¬ν•œ μš”μ²­μ„ κ΅¬ν˜„ν•œλ‹€. application은 browsing environmentκ°€ μ‘΄μž¬ν•˜λ˜μ§€ 그렇지 μ•Šλ˜μ§€μ— λŒ€ν•œ μ •λ³΄λΌ κ°€μ§€κ³  μžˆμ§€ μ•Šλ‹€. application κ³Ό browsing μ„œλΈŒμ‹œμŠ€ν…œ μ‚¬μ΄μ—λŠ” 좔상적인 결합관계가 μžˆλ‹€.

Choices operating system CIRM93 은 λ§Žμ€ frameworkλΌ ν•˜λ‚˜λ‘œ ν•©μΉ˜κΈ° μœ„ν•΄ facadeλΌ μ‚¬μš©ν•œλ‹€. Choicesμ—μ„œμ˜ keyκ°€ λ˜λŠ” 좔상객체듀은 process와 storge, 그리고 adress spaces 이닀. μ΄λŸ¬ν•œ 각 μΆ”μƒκ°μ²΄λ“€μ—λŠ” 각각에 λŒ€μ‘λ˜λŠ” μ„œλΈŒμ‹œμŠ€ν…œμ΄ 있으며, frameworkλ‘œμ„œ κ΅¬ν˜„λœλ‹€. 이 frameworkλŠ” λ‹€μ–‘ν•œ ν•˜λ“œμ›¨μ–΄ ν”Œλž«νΌμ— λŒ€ν•΄ Choices에 λŒ€ν•œ porting을 μ§€μ›ν•œλ‹€. 이 두 μ„œλΈŒμ‹œμŠ€ν…œμ€ 'λŒ€ν‘œμž'λΌ κ°€μ§„λ‹€. (즉, facade) 이 λŒ€ν‘œμžλ“€μ€ FileSystemInterface (storage) 와 Domain (address spaces)이닀.


μ˜ˆλΌ λ“€μ–΄, 가상 λ©”λͺ¨λ¦¬ frameworkλŠ” Domain을 facadeλ‘œμ„œ 가진닀. Domain은 address spaceλΌ λ‚˜νƒ€λ‚Έλ‹€. Domain은 virtual addresses 와 λ©”λͺ¨λ¦¬ 객체, 화일, μ €μž₯μ†Œμ˜ offset에 λ§€ν•‘ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€. Domain의 main operation은 νŠΉμ • μ£Όμ†Œμ— λŒ€ν•΄ λ©”λͺ¨λ¦¬ κ°μ²΄λΌ μΆ”κ°€ν•˜κ±°λ‚˜, μ‚­μ œν•˜λ„ˆκ°€ page faultλΌ λ‹€λ£¨λŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.

μ•žμ˜ λ‹€μ΄μ–΄κ·Έλž¨μ΄ 보여주λ“, 가상 λ©”λͺ¨λ¦¬ μ„œλΈŒμ‹œμŠ€ν…œμ€ λ‚΄λΆ€μ μœΌλ‘œ λ‹€μŒκ³Ό 같은 μ»΄ν¬λ„ŒνŠΈλΌ μ΄μš©ν•œλ‹€.

  • MemoryObject λŠ” 데이터 μ €μž₯μ†ŒλΌ λ‚˜νƒ€λ‚Έλ‹€.
  • MemoryObjectCacheλŠ” 물리적 λ©”λͺ¨λ¦¬μ—μ„œμ˜ MemoryObject의 λ°μ΄ν„°λΌ μΊμ‰¬ν•œλ‹€.
    MemoryObjectCacheλŠ” μ‹€μ œλ‘œλŠ” 캐쉬 정책을 μ§€μ—­ν™”μ‹œν‚€λŠ” Strategy Pattern이닀.
  • AddressTranslation 은 address translation hardware λΌ μΊ‘μŠν™”ν•œλ‹€.

    RepairFault λͺ…령은 page fault μΈν„°λŸ½νŠΈκ°€ μΌμ–΄λ‚ λ•Œ ν˜ΈμΆœλœλ‹€. Domain은 fault λΌ μ•ΌκΈ°μ‹œν‚¨ μ£Όμ†Œμ˜ λ©”λͺ¨λ¦¬κ°μ²΄λΌ 찾은뒀 RepairFault에 λ©”λͺ¨λ¦¬κ°μ²΄κ³Ό κ΄€κ³„λœ μΊμ‰¬λΌ μœ„μž„ν•œλ‹€. Domain듀은 μ»΄ν¬λ„ŒνŠΈλΌ κ΅μ²΄ν•¨μœΌλ‘œμ„œ μ»€μŠ€ν„°λ§ˆμ΄μ¦ˆλ  수 μžˆλ‹€.

1.9. Related Patterns

AbstactFactory λŠ” Facadeκ΅¬ν˜„μ‹œ μ„œλΈŒμ‹œμŠ€ν…œ 독립적인 λ°©λ²•μœΌλ‘œ μ„œλΈŒμ‹œμŠ€ν…œ κ°μ²΄λΌ λ§Œλ“€ 수 μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€λΌ μ œκ³΅ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•œλ‹€. Abstract FactoryλŠ” λ˜ν•œ ν”Œλž«νΌ 비독립적 ν΄λž˜μŠ€λΌ κ°μΆ”κΈ° μœ„ν•΄ Facade의 λŒ€μ•ˆμœΌλ‘œμ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

Mediator λŠ” μ‘΄μž¬ν•˜λŠ” classλ“€μ˜ κΈ°λŠ₯듀을 μΆ”μƒν™”μ‹œν‚¨λ‹€λŠ” μ μ—μ„œ Facade와 λΉ„μŠ·ν•˜λ‹€. ν•˜μ§€λ§Œ Mediator의 λͺ©μ μ€ 정해지지 μ•Šμ€ λ™λ£Œν΄λž˜μŠ€κ°„μ˜ 톡신을 μΆ”μƒν™”μ‹œν‚€κ³ , ν•΄λ‹Ή λ™λ£Œν΄λž˜μŠ€κ΅° 어디에도 ν¬ν•¨λ˜μ§€ μ•ŠλŠ” κΈ°λŠ₯듀을 μ€‘μ•™μœΌλ‘œ λͺ¨μ€λ‹€. Mediator의 λ™λ£Œν΄λž˜μŠ€λ“€μ€ Mediator에 λŒ€ν•œ μ •λ³΄λΌ κ°€μ§€λ©° μ„œλ‘œ μ§μ ‘μ μœΌλ‘œ ν†΅μ‹ ν•˜λŠ” λŒ€μ‹  mediatorλΌ ν†΅ν•΄ ν†΅μ‹ ν•œλ‹€. λŒ€μ‘°μ μœΌλ‘œ facadeλŠ” 단지 μ„œλΈŒμ‹œμŠ€ν…œλ“€μ„ μ‚¬μš©ν•˜κΈ° νŽΈν•˜κ²Œ ν•˜κΈ° μœ„ν•΄μ„œ μ„œλΈŒμ‹œμŠ€ν…œλ“€μ˜ μΈν„°νŽ˜μ΄μŠ€λΌ μΆ”μƒν™”μ‹œν‚¬ 뿐이닀. facadeλŠ” μƒˆλ‘œμš΄ κΈ°λŠ₯을 μƒˆλ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©°, μ„œλΈŒμ‹œμŠ€ν…œ ν΄λž˜μŠ€λŠ” facade에 λŒ€ν•œ μ •λ³΄λΌ κ°€μ§ˆ ν•„μš”κ°€ μ—†λ‹€.

보톡 facadeλŠ” 단일 였브젝트둜 μš”κ΅¬λœλ‹€. κ·Έλž˜μ„œFacade κ°μ²΄λŠ” μ’…μ’… SingletonPattern으둜 κ΅¬ν˜„λœλ‹€.

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:18
Processing time 0.0631 sec