์ต์ ๋ฒ ํจํด์ด๋?
Observer Pattern(์ต์ ๋ฒ)์ด๋ ๊ด์ฐฐ ์ค์ธ ๊ฐ์ฒด์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ฅผ ์ฌ๋ฌ ๋ค๋ฅธ ๊ฐ์ฒด์ ์๋ฆฌ๋ ๋ฉ์ปค๋์ฆ์ ์ ์ํ ์ ์๋ ๋์์ธ ํจํด์ ๋๋ค. iOS์์๋ Swift 5.1 ๋ฒ์ ๋ถํฐ Combine ํ๋ ์์ํฌ์ Publisher๊ฐ ์ถ๊ฐ๋์ด ์ด๋ฅผ ์ฌ์ฉํ ์ ์๊ณ NotificationCenter๋ ๋น์ทํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- Subject (Publisher)
- Observer๋ค์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ ๊ฐ์๋ ์ ํ์ด ์์ต๋๋ค.
- Observer๋ค์ ์ถ๊ฐ, ์ ๊ฑฐํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Concrete Subject (Publisher)
- Concrete Observer ๊ฐ์ฒด์ ์ํ๋ฅผ ์ ์ฅํฉ๋๋ค.
- ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด Observer(Subscriber)์๊ฒ ์๋ฆฝ๋๋ค.
- Observer (Subscriber)
- ๊ฐ์ฒด์ ๋ณ๊ฒฝ ์ฌํญ์ ์๋ ค์ผํ๋ ๊ฐ์ฒด์ ๋ํ Update ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด
- Concrete Observer (Subscriber)
- Concrete Subject (Publisher) ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํฉ๋๋ค.
- Subject(Publisher)์ ์ํ์ ์ผ๊ด์ฑ์ ์ ์งํฉ๋๋ค.
- ๊ฐ์ฒด์ ์ํ์ ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ ์ํด update ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํฉ๋๋ค.
์ต์ ๋ฒ ํจํด์ ์ธ์ ์ฐ๋์?
๋ค๋ฅธ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ด๋ค ํ๋์ ํ๊ณ ์ถ๋ค๋ฉด ์ต์ ๋ฒ ํจํด์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. ์ด๋ฌํ ํจํด์ iOS์์๋ ViewController์ Observer(Subscriber)๊ฐ ์๊ณ , Model์ Subject(Publisher)๊ฐ ์๋ MVC ํจํด์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด Model์ ViewController์ ํ์ ์ ๋ํด ์ ํ์ ์์ด ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์ด๋ฅผ ViewController์ ์ ๋ฌํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฌ๋ฌ ๊ฐ์ ViewController๊ฐ ํ๋์ Model์ ๋ณ๊ฒฝ์ฌํญ์ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
ํ์ค์์ ์ต์ ๋ฒ ํจํด์ ์ฌ์ฉํ๋ ์ํฉ์ ์ดํดํด๋ณด์๋ฉด, ์ ํ ๋งค์ฅ์ ์์ดํฐ์ด ๋งค์ง ์ํ๋ผ๊ณ ํด๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋์ ์์ดํฐ์ด ์ ๊ณ ๋ ๋ DB์ ๋ชจ๋ ๊ณ ๊ฐ์๊ฒ ์์ดํฐ ์ ๊ณ ์๋ฆผ์ ์ฃผ๊ฒ ๋๋ฉด ๋๊ตฐ๊ฐ์๊ฒ๋ ์ข์ ์๋ฆผ์ด์ง๋ง ๋๊ตฐ๊ฐ์๊ฒ๋ ์คํธ์ด ๋ ์ ์๊ฒ ์ฃ ? ๋ฐ๋ผ์ ์์ดํฐ์ด ์ ๊ณ ๋ ๋ ์๋ฆผ์ ๋ฐ๊ณ ์ถ์ ๊ณ ๊ฐ์ ๋ํด์๋ง ํด๋น ์๋ฆผ์ ์ฃผ๋ ๋ฑ์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด ์ข์ ๊ฒ ๊ฐ์์. ์ด๋ด ๋ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์ต์ ๋ฒ ํจํด์ ๋๋ค.
์ต์ ๋ฒ ํจํด์ ๊ฒฐ๊ณผ?
์ฅ์
- Open / Close ์์น์ ์งํฌ ์ ์์ต๋๋ค. Subject(Publisher)์ ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ์๋ก์ด Observer(Subscriber) ํด๋์ค๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค. ๋ฌผ๋ก ๊ทธ ๋ฐ๋๋ ๊ฐ๋ฅํฉ๋๋ค.
- ๋ฐํ์์์ ๊ฐ์ฒด๊ฐ ๊ด๊ณ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
๋จ์
- Observer(Subscriber)์๊ฒ ์๋ฆผ์ด ๊ฐ๋ ์์๋ ๋ณด์ฅํ์ง ์์ต๋๋ค.
- Observer, Subject์ ๊ด๊ณ๊ฐ ์ ์ ์๋์ง ์์ผ๋ฉด ์ํ์ง ์๋ ๋์์ด ๋ฐ์ํ ์๋ ์์ต๋๋ค.
์์
๊ทธ๋ผ Observer Pattern์ Swift ์ธ์ด๋ก ๊ฐ๋จํ๊ฒ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
Combine ํ๋ ์์ํฌ๋ NotificationCenter๋ก ๊ตฌํ ํ ์๋ ์์ง๋ง, ๊ทธ๋ฅ ์ง์ ๊ฐ๋จํ๊ฒ ํ ๋ฒ ๊ตฌํํด๋ณผ๊ฒ์.
์๊น ์ ํ ๋งค์ฅ์ ์์ดํฐ์ด ๋งค์ง๋ ์ํฉ์ ๊ตฌํํด๋ณด๋ฉด ์ฌ๋ฐ์๊ฒ ๊ฐ์ผ๋ ๊ทธ ์ํฉ์ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ Subject(Publisher) ์ธํฐํ์ด์ค๋ฅผ ์ ์ํฉ๋๋ค.
// Subject(Publisher) Interface
protocol Publisher {
var observers: [Observer] { get set }
func subscribe(observer: Observer)
func unSubscribe(observer: Observer)
func notify(message: String)
}
์ต์ ๋ฒ๋ฅผ ์ถ๊ฐํ๋ subscribe, ์ต์ ๋ฒ๋ฅผ ์ ๊ฑฐํ๋ unSubscribe, ์ถ๊ฐ๋ ์ต์ ๋ฒ๋ค์๊ฒ ์๋ฆผ์ ๋ณด๋ด๋ notify ๋ฉ์๋๋ฅผ ๊ฐ์ ธ์ผ ํ๋ ํ๋กํ ์ฝ์ ์ ์ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค ์ฌ๊ธฐ์ ์ฌ์ฉํ๋ Observer ํ๋กํ ์ฝ์ ์ ์ํด์ค๋๋ค.
// Observer(Subscriber) Interface
protocol Observer {
var id: String { get set }
func update(message: String)
}
๊ทธ๋ผ ์ด์ Publisher ์ญํ ์ ํ๋ Apple Store ํด๋์ค๋ฅผ ์ ์ํฉ๋๋ค.
// Concrete Subject(Publisher)
class AppleStore: Publisher {
var observers: [Observer]
init(observers: [Observer]) {
self.observers = observers
}
func subscribe(observer: Observer) {
self.observers.append(observer)
}
func unSubscribe(observer: Observer) {
if let index = self.observers.firstIndex(where: { $0.id == observer.id }) {
self.observers.remove(at: index)
}
}
func notify(message: String) {
for observer in observers {
observer.update(message: message)
}
}
}
๊ทธ๋ฆฌ๊ณ AppleStore์ ์๋์ ์์ ํ Customer ํด๋์ค๋ ์ ์ํด์ค๋๋ค.
// Concrete Observer(Subscriber)
class Customer: Observer {
var id: String
init(id: String) {
self.id = id
}
func update(message: String) {
print("\(id)๋ \(message)์์ \n")
}
}
์ด๋ ๊ฒ ํ๋ฉด ๊ฐ๋จํ๊ฒ Observer Pattern์ ๋ชจ๋ ๊ตฌํ ํ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ผ ์ ์๋ํ๋์ง ์คํํด๋ณด๊ฒ ์ต๋๋ค!
์์ ์ฝ๋๋ฅผ ์คํํ๊ฒ ๋๋ฉด ์์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
appleStore์ ์๋ฆผ์ ๋ฐ๋ Customer ๊ฐ์ฒด์ธ pingu, roby๋ฅผ ์ถ๊ฐํด์ฃผ๊ณ notify ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด 2๋ช ์ Customer ๊ฐ์ฒด์ ์ ์ ๋ฌ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค roby๋ฅผ unSubscribe๋ก ์ ๊ฑฐํด์ค ๋ค notify ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด Pingu ๊ฐ์ฒด์๋ง ์ ๋ฌ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
\