Design Patterns - Observer Pattern [1]

JBBΒ·2020λ…„ 7μ›” 27일
1

DesingPatterns

λͺ©λ‘ 보기
2/2
post-thumbnail

πŸ“šΒ Observer Pattern (μ˜΅μ €λ²„ νŒ¨ν„΄)

μ§€λ‚œ μ‹œκ°„ μš°λ¦¬λŠ” μ „λž΅ νŒ¨ν„΄μ— λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.
이번 μ‹œκ°„μ—” μ˜΅μ €λ²„ νŒ¨ν„΄μ— λŒ€ν•΄ μ•Œμ•„λ³Ό μ‹œκ°„μž…λ‹ˆλ‹€.

Code Example

πŸ€”Β Observer Pattern(μ˜΅μ €λ²„ νŒ¨ν„΄)μ΄λž€ λ¬΄μ—‡μΌκΉŒμš”?

πŸ“‘Β μœ„ν‚€λ°±κ³Ό
βœπŸΌΒ μ˜΅μ €λ²„ νŒ¨ν„΄μ€ 객체의 μƒνƒœ λ³€ν™”λ₯Ό κ΄€μ°°ν•˜λŠ” κ΄€μ°°μžλ“€,
     즉 μ˜΅μ €λ²„λ“€μ˜ λͺ©λ‘μ„ 객체에 λ“±λ‘ν•˜μ—¬ μƒνƒœ λ³€ν™”κ°€ μžˆμ„ λ•Œλ§ˆλ‹€ λ©”μ„œλ“œ 등을 톡해
     객체가 직접 λͺ©λ‘μ˜ 각 μ˜΅μ €λ²„λ“€μ—κ²Œ ν†΅μ§€ν•˜λ„λ‘ ν•˜λŠ” λ””μžμΈ νŒ¨ν„΄μž…λ‹ˆλ‹€.
     주둜 λΆ„μ‚° 이벀트 핸듀링 μ‹œμŠ€ν…œμ„ κ΅¬ν˜„ν•˜λŠ”λ° μ‚¬μš©λ©λ‹ˆλ‹€.

πŸ”Β λ­”κ°€ μ€‘μš”ν•œ 일이 일어났을 λ•Œ, κ°μ²΄λ“€ν•œν…Œ μ†Œμ‹μ„ μ•Œλ € 쀄 수 μžˆλŠ” νŒ¨ν„΄μž…λ‹ˆλ‹€.
     객체 μͺ½μ—μ„œλŠ” κ³„μ†ν•΄μ„œ 정보λ₯Ό 받을지 μ—¬λΆ€λ₯Ό 싀행쀑에 결쑍할 수 μžˆμŠ΅λ‹ˆλ‹€.
Β Β Β Β Β μ˜΅μ €λ²„ νŒ¨ν„΄μ€ JDKμ—μ„œ κ°€μž₯ 많이 μ“°μ΄λŠ” νŒ¨ν„΄ κ°€μš΄λ° ν•˜λ‚˜μ΄κΈ°λ„ ν•©λ‹ˆλ‹€.

πŸ“‹Β μ˜ˆμ œλ₯Ό 보며 μ•Œμ•„λ΄…μ‹œλ‹€

πŸ“‘Β κΈ°μƒ λͺ¨λ‹ˆν„°λ§ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ κ°œμš”

이 μ‹œμŠ€ν…œμ€ 기상청과 WeatherData(κΈ°μƒμ²­μœΌλ‘œλΆ€ν„° μ˜€λŠ” 데이터λ₯Ό μΆ”μ ν•˜λŠ” 객체),
그리고 μ‚¬μš©μžμ—κ²Œ ν˜„μž¬ 기상 쑰건을 λ³΄μ—¬μ£ΌλŠ” λ””μŠ€ν”Œλ ˆμ΄, μ΄λ ‡κ²Œ μ„Έ μš”μ†Œλ‘œ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

πŸ’»Β WeatherData 클래슀λ₯Ό μ—΄μ–΄λ΄…μ‹œλ‹€

WeatherData ν΄λž˜μŠ€μ—λŠ” μ„Έ 가지 μΈ‘μ •κ°’(μ˜¨λ„, μŠ΅λ„, κΈ°μ••)을 μ•Œμ•„λ‚΄κΈ° μœ„ν•œ λ©”μ†Œλ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€.
μƒˆλ‘œμš΄ 기상 μΈ‘μ • 데이터가 λ‚˜μ˜¬ λ•Œλ§ˆλ‹€ WeatherData 클래슀의
measurementsChanged( ) λ©”μ†Œλ“œκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.
기상 데이터λ₯Ό μ‚¬μš©ν•˜λŠ” μ—¬λŸ¬κ°€μ§€ λ””μŠ€ν”Œλ ˆμ΄ ν•­λͺ©μ„ κ΅¬ν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€.
λ˜ν•œ, WeatherDataμ—μ„œ μƒˆλ‘œμš΄ 츑정값이 λ“€μ–΄μ˜¬ λ•Œλ§ˆλ‹€ λ””μŠ€ν”Œλ ˆμ΄λ₯Ό κ°±μ‹ ν•΄μ•Ό ν•©λ‹ˆλ‹€.
μΆ”κ°€λ‘œ μ‹œμŠ€ν…œμ΄ ν™•μž₯ κ°€λŠ₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.
λ‹€λ₯Έ κ°œλ°œμžλ“€μ΄ λ³„λ„μ˜ λ””μŠ€ν”Œλ ˆμ΄ ν•­λͺ©μ„ λ§Œλ“€ 수 μžˆλ„λ‘ ν•΄μ•Ό ν•˜κ³ ,
μ‚¬μš©μžλ“€μ΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ λ§ˆμŒλŒ€λ‘œ λ””μŠ€ν”Œλ ˆμ΄ ν•­λͺ©μ„ μΆ”κ°€/제거 ν•  수 μžˆλ„λ‘ ν•΄μ•Όν•©λ‹ˆλ‹€.

πŸ“–Β μ˜΅μ €λ²„ νŒ¨ν„΄μ— λŒ€ν•΄ μ’€ 더 μžμ„Ένžˆ μ•Œμ•„λ΄…μ‹œλ‹€.

πŸ”Β μ˜΅μ €λ²„ νŒ¨ν„΄μ—μ„œλŠ” ν•œ 객체의 μƒνƒœκ°€ λ°”λ€Œλ©΄
Β Β Β Β Β κ·Έ 객체에 μ˜μ‘΄ν•˜λŠ” λ‹€λ₯Έ κ°μ²΄λ“€ν•œν…Œ 연락이 κ°€κ³ ,
Β Β Β Β Β μžλ™μœΌλ‘œ λ‚΄μš©μ΄ κ°±μ‹ λ˜λŠ” λ°©μ‹μœΌλ‘œ
Β Β Β Β Β μΌλŒ€λ‹€ (one-to-many) μ˜μ‘΄μ„±μ„ μ •μ˜ν•©λ‹ˆλ‹€.

μΌλŒ€λ‹€ κ΄€κ³„λŠ” μ£Όμ œμ™€ μ˜΅μ €λ²„μ— μ˜ν•΄ μ •μ˜λ©λ‹ˆλ‹€. μ˜΅μ €λ²„λŠ” μ£Όμ œμ— μ˜μ‘΄ν•˜κ³ ,
주제의 μƒνƒœκ°€ λ°”λ€Œλ©΄ μ˜΅μ €λ²„ν•œν…Œ 연락을 ν•©λ‹ˆλ‹€.
연락 방법에 따라 μ˜΅μ €λ²„μ— μžˆλŠ” 값이 μƒˆλ‘œμš΄ κ°’μœΌλ‘œ 갱신될 수 도 μžˆμŠ΅λ‹ˆλ‹€.

μ˜΅μ €λ²„ νŒ¨ν„΄μ„ κ΅¬ν˜„ν•˜λŠ” λ°©λ²•μ—λŠ” μ—¬λŸ¬κ°€μ§€κ°€ μžˆμ§€λ§Œ,
λŒ€λΆ€λΆ„ 주제(Subject) μΈν„°νŽ˜μ΄μŠ€ 와 μ˜΅μ €λ²„(Observer) μΈν„°νŽ˜μ΄μŠ€κ°€
λ“€μ–΄μžˆλŠ” 클래슀 λ””μžμΈμ„ λ°”νƒ•μœΌλ‘œ ν•©λ‹ˆλ‹€.

πŸ•ŽΒ μ˜΅μ €λ²„ νŒ¨ν„΄: 클래슀 λ‹€μ΄μ–΄κ·Έλž¨

  1. 주제λ₯Ό λ‚˜νƒ€λ‚΄λŠ” Subject μΈν„°νŽ˜μ΄μŠ€ μž…λ‹ˆλ‹€.
    κ°μ²΄μ—μ„œ μ˜΅μ €λ²„λ‘œ λ“±λ‘ν•˜κ±°λ‚˜ μ˜΅μ €λ²„ λͺ©λ‘μ—μ„œ νƒˆν‡΄ν•˜κ³  싢을 λ•ŒλŠ”
    이 μΈν„°νŽ˜μ΄μŠ€μ— μžˆλŠ” λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

  2. 각 μ£Όμ œλ§ˆλ‹€ μ—¬λŸ¬κ°œμ˜ μ˜΅μ €λ²„κ°€ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

  3. μ˜΅μ €λ²„κ°€ 될 κ°€λŠ₯성이 μžˆλŠ” κ°μ²΄μ—μ„œλŠ” λ°˜λ“œμ‹œ Observer μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    이 μΈν„°νŽ˜μ΄μŠ€μ—λŠ” 주제의 μƒνƒœκ°€ λ°”λ€Œμ—ˆμ„ λ•Œ ν˜ΈμΆœλ˜λŠ” update( ) λ©”μ†Œλ“œ 밖에 μ—†μŠ΅λ‹ˆλ‹€.

  4. Observer μΈν„°νŽ˜μ΄μŠ€λ§Œ κ΅¬ν˜„ν•œλ‹€λ©΄ 무엇이든 μ˜΅μ €λ²„ ν΄λž˜μŠ€κ°€ 될 수 μžˆμŠ΅λ‹ˆλ‹€.
    각 μ˜΅μ €λ²„λŠ” νŠΉμ • 주제 객체에 등둝을 ν•΄μ„œ 연락을 받을 수 μžˆμŠ΅λ‹ˆλ‹€.

  5. 주제 역할을 ν•˜λŠ” ꡬ상 ν΄λž˜μŠ€μ—μ„œλŠ” 항상 Subject μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€.
    주제 ν΄λž˜μŠ€μ—μ„œλŠ” 등둝 및 해지λ₯Ό μœ„ν•œ λ©”μ†Œλ“œ 외에 μƒνƒœκ°€ λ°”λ€”λ•Œλ§ˆλ‹€
    λͺ¨λ“  μ˜΅μ €λ²„λ“€μ—κ²Œ 연락을 ν•˜κΈ° μœ„ν•œ notifyObservers( ) λ©”μ†Œλ“œλ„ κ΅¬ν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€.

  6. 주제 ν΄λž˜μŠ€μ—λŠ” μƒνƒœλ₯Ό μ„€μ •ν•˜κ³  μ•Œμ•„λ‚΄κΈ° μœ„ν•œ
    Gettet/Setter λ©”μ†Œλ“œκ°€ λ“€μ–΄μžˆμ„ 수 도 μžˆμŠ΅λ‹ˆλ‹€.

  1. πŸ€”Β μ΄κ±°λž‘ μΌλŒ€λ‹€ κ΄€κ³„λž‘ 무슨 관계가 μžˆλŠ”κ±°μ£ ?

    πŸ”Β μ˜΅μ €λ²„ νŒ¨ν„΄μ—μ„œ μƒνƒœλ₯Ό μ €μž₯ν•˜κ³  μ§€λ°°ν•˜λŠ” 것은 주제 객체 μž…λ‹ˆλ‹€.
    Β Β Β Β Β λ”°λΌμ„œ μƒνƒœκ°€ λ“€μ–΄μžˆλŠ” κ°μ²΄λŠ” ν•˜λ‚˜λ§Œ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
    Β Β Β Β Β μ˜΅μ €λ²„λ₯Ό μ‚¬μš©ν•˜κΈ΄ ν•˜μ§€λ§Œ λ°˜λ“œμ‹œ μƒνƒœλ₯Ό 가지고 μžˆμ–΄μ•Ό ν•˜λŠ” 것은 μ•„λ‹™λ‹ˆλ‹€.
    Β Β Β Β Β λ”°λΌμ„œ, μ˜΅μ €λ²„λŠ” μ—¬λŸ¬ κ°œκ°€ μžˆμ„ 수 있으며,
         주제 κ°μ²΄μ—μ„œ μƒνƒœκ°€ λ°”λ€Œμ—ˆλ‹€λŠ” 것을 μ•Œλ €μ£ΌκΈ°λ₯Ό κΈ°λ‹€λ¦¬λŠ”,
    Β Β Β Β Β μ£Όμ œμ— 의쑴적인 μ„±μ§ˆμ„ κ°€μ§€κ²Œ 되죠.
    Β Β Β Β Β κ·ΈλŸ¬λ―€λ‘œ ν•˜λ‚˜μ˜ μ£Όμ œμ™€ μ—¬λŸ¬ 개의 μ˜΅μ €λ²„κ°€ μ—°κ΄€λœ,
    Β Β Β Β Β μΌλŒ€λ‹€ (One-To-Many) 관계가 μ„±λ¦½λ©λ‹ˆλ‹€.

  2. πŸ€”Β μ˜μ‘΄μ„±μ΄ 이 λ‚΄μš©μ΄λž‘ 무슨 상관이 μžˆμ–΄μš”?

    πŸ”Β λ°μ΄ν„°μ˜ 주인은 μ£Όμ œμž…λ‹ˆλ‹€.
    Β Β Β Β Β μ˜΅μ €λ²„λŠ” 데이터가 λ³€κ²½λ˜μ—ˆμ„ λ•Œ μ£Όμ œμ—μ„œ κ°±μ‹ ν•΄μ£ΌκΈ°λ₯Ό
    Β Β Β Β Β κΈ°λ‹€λ¦¬λŠ” μž…μž₯이기 λ•Œλ¬Έμ— μ˜μ‘΄μ„±μ„ 가진닀고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
         이런 방법을 μ‚¬μš©ν•˜λ©΄ μ—¬λŸ¬ κ°μ²΄μ—μ„œ λ™μΌν•œ 데이터λ₯Ό μ œμ–΄ν•˜λ„λ‘
    Β Β Β Β Β ν•˜λŠ” 것에 λΉ„ν•΄ 더 κΉ”λ”ν•œ 객체지ν–₯ λ””μžμΈμ„ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ•ŽΒ μ˜΅μ €λ²„ νŒ¨ν„΄: 예제 클래슀 λ‹€μ΄μ–΄κ·Έλž¨

μœ„μ˜ λ‹€μ΄μ–΄κ·Έλž¨κ³Ό μ‹€μ œ 예제λ₯Ό κ΅¬ν˜„ν•  클래슀 λ‹€μ΄μ–΄κ·Έλž¨μ„ λΉ„κ΅ν•΄λ΄…μ‹œλ‹€.
κ΅¬ν˜„ν•œ μ½”λ“œλŠ” Code Example κΉƒν—ˆλΈŒ μ €μž₯μ†Œμ—μ„œ 보싀 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ’‘Β λŠμŠ¨ν•œ κ²°ν•© (Loose Coupling)의 μœ„λ ₯

두 객체가 λŠμŠ¨ν•˜κ²Œ κ²°ν•©λ˜μ–΄ μžˆλ‹€λŠ” 것은, κ·Έ λ‘˜μ΄ μƒν˜Έμž‘μš©μ„ ν•˜κΈ΄ ν•˜μ§€λ§Œ
μ„œλ‘œμ— λŒ€ν•΄ 잘 λͺ¨λ₯Έλ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.

μ˜΅μ €λ²„ νŒ¨ν„΄μ—μ„œλŠ” μ£Όμ œμ™€ μ˜΅μ €λ²„κ°€ λŠμŠ¨ν•˜κ²Œ κ²°ν•©λ˜μ–΄ μžˆλŠ” 객체 λ””μžμΈμ„ μ œκ³΅ν•©λ‹ˆλ‹€.
κ·Έ μ΄μœ μ— λŒ€ν•΄ μ•Œμ•„λ΄…μ‹œλ‹€.

Subject(주제)κ°€ Observer(μ˜΅μ €λ²„)에 λŒ€ν•΄μ„œ μ•„λŠ” 것은
Observerκ°€ νŠΉμ • μΈν„°νŽ˜μ΄μŠ€(Observer μΈν„°νŽ˜μ΄μŠ€)λ₯Ό κ΅¬ν˜„ν•œλ‹€λŠ” 것 λΏμž…λ‹ˆλ‹€.
Observer의 ꡬ상 ν΄λž˜μŠ€κ°€ 무엇인지,
Observerκ°€ 무엇을 ν•˜λŠ”μ§€ 등에 λŒ€ν•΄μ„œλŠ” μ•Œ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

ObserverλŠ” μ–Έμ œλ“ μ§€ μƒˆλ‘œ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
SubjectλŠ” Observer μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 객체의 λͺ©λ‘μ—λ§Œ μ˜μ‘΄ν•˜κΈ° λ•Œλ¬Έμ—
μ–Έμ œλ“ μ§€ μƒˆλ‘œμš΄ Observerλ₯Ό μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 사싀 싀행쀑에 ν•œ Observerλ₯Ό 바꿔도 되고,
κ·Έλ ‡κ²Œ 해도 Subject κ°μ²΄λŠ” κ³„μ†ν•΄μ„œ 데이터λ₯Ό 보낼 수 μžˆμŠ΅λ‹ˆλ‹€.
λ§ˆμ°¬κ°€μ§€λ‘œ Observerλ₯Ό μ•„λ¬΄λ•Œλ‚˜ μ œκ±°ν•΄λ„ λ©λ‹ˆλ‹€.

μƒˆλ‘œμš΄ ν˜•μ‹μ˜ Observerλ₯Ό μΆ”κ°€ν•˜λ €κ³  ν•  λ•Œλ„ Subjectλ₯Ό μ „ν˜€ λ³€κ²½ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.
Observerκ°€ λ˜μ–΄μ•Ό ν•˜λŠ” μƒˆλ‘œμš΄ ꡬ상 ν΄λž˜μŠ€κ°€ 생겼닀고 κ°€μ •ν•΄ λ΄…μ‹œλ‹€.
이 λ•Œλ„ μƒˆλ‘œμš΄ 클래슀 ν˜•μ‹μ„ 받아듀일 수 μžˆλ„λ‘ Subjectλ₯Ό λ°”κΏ”μ•Ό ν•  ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€.
μƒˆλ‘œμš΄ ν΄λž˜μŠ€μ—μ„œ Observer μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ³ , Observer둜 λ“±λ‘ν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.
Subject κ°μ²΄λŠ” μ „ν˜€ 신경도 쓰지 μ•Šμ•„λ„ λ©λ‹ˆλ‹€.

Subject와 ObserverλŠ” μ„œλ‘œ λ…λ¦½μ μœΌλ‘œ μž¬μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
Subjectλ‚˜ Observerλ₯Ό λ‹€λ₯Έ μš©λ„λ‘œ ν™œμš© ν•  일이 μžˆλ‹€κ³  해도 μ†μ‰½κ²Œ μž¬μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
κ·Έ λ‘˜μ΄ μ„œλ‘œ λ‹¨λ‹¨ν•˜κ²Œ κ²°ν•©λ˜μ–΄ μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

Subjectλ‚˜ Observerκ°€ λ°”λ€Œλ”λΌλ„ μ„œλ‘œν•œν…Œ 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
λ‘˜μ΄ μ„œλ‘œ λŠμŠ¨ν•˜κ²Œ κ²°ν•©λ˜μ–΄ 있기 λ•Œλ¬Έμ— Subject ν˜Ήμ€ Observer μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œλ‹€λŠ”
쑰건만 λ§Œμ‘±λœλ‹€λ©΄ μ–΄λ–»κ²Œ 바꿔도 λ¬Έμ œκ°€ μƒκΈ°λŠ” 일은 μ—†μŠ΅λ‹ˆλ‹€.

βœπŸΌΒ λ””μžμΈ νŒ¨ν„΄μ˜ μƒˆλ‘œμš΄ 원칙을 μ•Œμ•„λ΄…μ‹œλ‹€.
Β Β Β Β Β μ„œλ‘œ μƒν˜Έμž‘μš©μ„ ν•˜λŠ” 객체 μ‚¬μ΄μ—μ„œλŠ” κ°€λŠ₯ν•˜λ©΄
Β Β Β Β Β λŠμŠ¨ν•˜κ²Œ κ²°ν•©ν•˜λŠ” λ””μžμΈμ„ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

λŠμŠ¨ν•˜κ²Œ κ²°ν•©ν•˜λŠ” λ””μžμΈμ„ μ‚¬μš©ν•˜λ©΄ λ³€κ²½ 사항이 생겨도
λ¬΄λ‚œνžˆ μ²˜λ¦¬ν•  수 μžˆλŠ” μœ μ—°ν•œ 객체지ν–₯ μ‹œμŠ€ν…œμ„ ꡬ좕할 수 μžˆμŠ΅λ‹ˆλ‹€.
객체 μ‚¬μ΄μ˜ μƒν˜Έμ˜μ‘΄μ„±μ„ μ΅œμ†Œν™” ν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

끝내며,

μ΄λ ‡κ²Œ μ˜΅μ €λ²„ νŒ¨ν„΄μ˜ 1λΆ€ ν¬μŠ€νŒ…μ΄ λλ‚¬μŠ΅λ‹ˆλ‹€.
2λΆ€μ—μ„œλŠ” μžλ°”μ˜ java.util.Observableκ³Ό
JDKμ—μ„œμ˜ Observer Pattern에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

0개의 λŒ“κΈ€