[์ค์ํํธ ๋์์ธํจํด] ํ/์ญ ํจํด(Publisher/Subscriber Pattern)
๋ฐํ/๊ตฌ๋ ํจํด (ํ์ญ/pubsub ํจํด์ด๋ผ๊ณ ํ๋๋ผ..)
์ง๋ ํฌ์คํธ์์ ์ต์ ๋ฒ ํจํด์ ๋ํด ์ ๋ฆฌํด๋ดค๋๋ฐ์, ์ต์ ๋ฒ ํจํด๊ณผ ์ ์ฌํ์ง๋ง ๋ ์ ์ฐํ ๊ตฌ์กฐ๋ฅผ ์ง๋ ํ/์ญ ํจํด์ผ๋ก ๋ถ๋ฆฌ๋ ๋ฐํ/๊ตฌ๋ ํจํด์ ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ต์ ๋ฒ ํจํด๊ณผ ๋น์ทํ๊ธฐ ๋๋ฌธ์ ํฌ๊ฒ ์ค๋ช ํ ๋ด์ฉ์ ์์ด ๋ณด์ฌ์! ์ต์ ๋ฒ ํจํด์ด ์์ง ๋ฏ์ค๋ค๋ฉด ์ด ํฌ์คํธ๋ฅผ ๋จผ์ ์ฝ์ด์ฃผ์ธ์!
์ต์ ๋ฒ ํจํด๊ณผ ๋ฌด์์ด ๋ค๋ฅธ๊ฐ์?
์ต์ ๋ฒ ํจํด์ฒ๋ผ ํ์ญ ํจํด๋ ์ด๋ค ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํค๋ Subject ๊ฐ์ฒด์, ๊ทธ ์ด๋ฒคํธ์ ๋ํ ์๋ฆผ์ ๋ฐ๊ธฐ ์ํด Subject๋ฅผ ๊ด์ฐฐํ๋ Observer ๊ฐ์ฒด๊ฐ ์กด์ฌํฉ๋๋ค. ํ์ง๋ง ์ค๊ฐ์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ธ๋ก์ปค๊ฐ ์กด์ฌํ๋ค๋ ์ ์์ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์ต์ ๋ฒ ํจํด์ Subject๋ ์์ ์ด ์ง์ Observer๋ค์ ๋ฐ์ ๊ด๋ฆฌํ๊ณ ์ด๋ฒคํธ์ ๋ํ ์๋ฆผ์ ๋ณด๋ ๋๋ค. ํ์ง๋ง ํ์ญ ํจํด์ Subject๋ ์ด๋ฒคํธ ๋ธ๋ก์ปค์๊ฒ ์ด๋ฒคํธ๋ฅผ ๋ณด๋ด๊ณ , ์ด๋ฒคํธ ๋ธ๋ก์ปค๊ฐ Observer ๋ค์๊ฒ ์๋ฆผ์ ๋ณด๋ด์ค๋๋ค. ์ค๊ฐ์ ํ ๊ณ์ธต์ด ๋ ์๊ธด ๊ฒ์ด์ฃ .
๋ง๋ค์ด๋ณด๊ธฐ
์ต์ ๋ฒ ํจํด์์ ๋ง๋ค์๋ ์์ ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๊ฒ ์ต๋๋ค.
import Foundation
protocol Observable {
func notify (post: String)
func add(follower: Follower)
func remove(follower: Follower)
}
protocol Followable {
func update (post: String)
}
class Celebrity: Observable {
let name: String
var followers: [Follower] = []
init(name: String) {
self.name = name
}
func notify(post: String) {
for follower in followers {
follower.update(post: post)
}
}
func add(follower: Follower) {
self.followers.append(follower)
}
func remove(follower: Follower) {
guard let removeIndex = followers.firstIndex(where: { $0 === follower }) else { return }
self.followers.remove(at: removeIndex)
}
}
class Follower: Followable {
let name: String
init(name: String) {
self.name = name
}
func update(post: String) {
print("\(name)์
๋๋ค! -> \(post)")
}
}
์ด์ ์ฐ์์ธ ๊ฐ์ฒด๋ ์์ ์ด ์ง์ ํ๋ก์๋ค์๊ฒ ์ด๋ฒคํธ๋ฅผ ๋ณด๋ด์ง ์๊ณ ์ค๊ฐ ๋ธ๋ก์ปค ๊ฐ์ฒด์๊ฒ ์ด๋ฒคํธ๋ฅผ ๋ณด๋ด์ผ ํฉ๋๋ค. ์ด๋ป๊ฒ ์์ ํ๋ฉด ์ข์๊น์?
์ค๊ฐ ๋ธ๋ก์ปค๋ฅผ ๋จผ์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค. ์ด ๋ธ๋ก์ปค๋ ์ด๋ค ์ฐ์์ธ์ ๋ํ ํ๋ก์ฐ ์ ๋ณด๋ฅผ ๋ชจ๋ ๊ฐ์ง๊ณ ์์ผ๋ฉด์ ์ฐ์๋ค์๊ฒ ์๋ก์ด ํฌ์คํ ์ ๋ฐ์ ํ๋ก์๋ค์๊ฒ ์ ๋ฌํด์ผ ํฉ๋๋ค.
class PostManager {
var celebrities : [Celebrity : [Follower]] = [:]
static let `default` = PostManager()
private init () {}
func add(follower: Follower, of celebrity: Celebrity) {
if celebrities[celebrity] != nil{
celebrities[celebrity]!.append(follower)
} else {
celebrities[celebrity] = [follower]
}
}
func remove(follower: Follower, of celebrity: Celebrity) {
if celebrities[celebrity] != nil {
guard let removeIndex = celebrities[celebrity]?.firstIndex(where: { $0 === follower }) else { return }
celebrities[celebrity]?.remove(at: removeIndex)
}
}
func notify(post: String, toFollowersOf celebrity: Celebrity) {
if celebrities[celebrity] != nil {
for follower in celebrities[celebrity]! {
follower.update(post: post)
}
}
}
}
ํฌ์คํธ ๋งค๋์ ๋ ์ฐ์์ธ๊ณผ ํ๋ก์๋ค์ ๋ชฉ๋ก์ ๋งตํํด์ ๋์ ๋๋ฆฌ๋ก ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ด์ ๋ถํฐ๋ ์ฐ์์ธ์ ์์ ์ ๋๊ฐ ํ๋ก์ฐ ํ๊ณ ์๋์ง ์ง์ ์ ์ ์๊ณ , ์ฌ์ง์ด๋ ํ๋ก์๋ค๋ ์์ ์ด ๋๊ตด ํ๋ก์ฐํ๊ณ ์๋์ง ์ง์ ์ ์ผ๋ก ์ ์ ์์ต๋๋ค.
ํฌ์คํธ ๋งค๋์ ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๊ตฌ์กฐ๊ฐ ์กฐ๊ธ ๋ฐ๋์ด์ผ ํ๊ฒ ์ฃ ? ์ด๋ฏธ ์ต์ ๋ฒ ํจํด์ ํตํด ์ฑ ์ ๋ถ๋ฆฌ๊ฐ ๋ช ํํ๊ฒ ๋์ด์์ด์ ์ฌ์ค ์์ ํ ๋ด์ฉ์ด ๋ง์ง๋ ์์ต๋๋ค. ๋จ์ํ ์ฐ์์ธ ๊ฐ์ฒด์๊ฒ ๋งก๊ฒจ์ ธ ์๋ ํ๋ก์๋ค์ ๊ด๋ฆฌํ๊ณ ์๋ฆผ์ ๋ณด๋ด๋ ์ฑ ์์ ํฌ์คํธ ๋งค๋์ ๋ก ๋๊ธฐ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
class Celebrity: Hashable, Observable {
let name: String
var followers: [Follower] = []
init(name: String) {
self.name = name
}
func notify(post: String) {
PostManager.default.notify(post: post, toFollowersOf: self)
}
func add(follower: Follower) {
PostManager.default.add(follower: follower, of: self)
}
func remove(follower: Follower) {
PostManager.default.remove(follower: follower, of: self)
}
static func == (lhs: Celebrity, rhs: Celebrity) -> Bool {
lhs === rhs
}
func hash(into hasher: inout Hasher) {
hasher.combine(name)
}
}
๋๋จธ์ง ์ฝ๋๋ ์ ํ ์์ ํ์ง ์๊ณ ์ต์ ๋ฒ ํจํด ๋์ ๋์ผํ ์ธ์คํด์ค ์์ฑ๊ณผ ๋ฉ์๋ ํธ์ถ์ ํด๋ณด๊ฒ ์ต๋๋ค.
let park = Celebrity(name: "๋ฐ๋ฒ๊ตฌ")
let han = Celebrity(name: "ํํธ์ด")
let ahn = Follower(name: "์์คํธ")
han.add(follower: ahn)
han.add(follower: Follower(name: "ํฉ์ฅ์"))
han.add(follower: Follower(name: "์กฐ์๋ด"))
han.notify(post: "ํธ๋์ด ์ด์ , ํธ์ด์ด์์~")
park.add(follower: ahn)
park.notify(post: "DP ๋ณต๊ท ์ํ๋?")
// ์์คํธ์
๋๋ค! -> ํธ๋์ด ์ด์ , ํธ์ด์ด์์~
// ํฉ์ฅ์์
๋๋ค! -> ํธ๋์ด ์ด์ , ํธ์ด์ด์์~
// ์กฐ์๋ด์
๋๋ค! -> ํธ๋์ด ์ด์ , ํธ์ด์ด์์~
// ์์คํธ์
๋๋ค! -> DP ๋ณต๊ท ์ํ๋?
์ด๋ ๊ฒ ๋์ผํ ์ถ๋ ฅ์ ํ์ธํ ์ ์์ต๋๋ค. ๋จ์ํ Subject์์ ํ๋ ์์ ์ ์ค๊ฐ ๊ณ์ธต์ธ ์ด๋ฒคํธ ๋ธ๋ก์ปค์๊ฒ ๋๊ฒจ์ค ๊ฒ๋ฟ์ด์ฃ .
let park = Celebrity(name: "๋ฐ๋ฒ๊ตฌ")
let han = Celebrity(name: "ํํธ์ด")
let ahn = Follower(name: "์์คํธ")
PostManager.default.add(follower: ahn, of: han)
PostManager.default.add(follower: Follower(name: "ํฉ์ฅ์"), of: han)
PostManager.default.add(follower: Follower(name: "์กฐ์๋ด"), of: han)
PostManager.default.notify(post: "ํธ๋์ด ์ด์ , ํธ์ด์ด์์~", toFollowersOf: han)
PostManager.default.add(follower: ahn, of: park)
PostManager.default.notify(post: "DP ๋ณต๊ท ์ํ๋?", toFollowersOf: park)
๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ์์ ํ๋ฉด ํ๋ก์ฐ, ํ๋ก์, ์ด๋ฒคํธ ๋ฐํ๊น์ง ๋ชจ๋ ์ค๊ฐ ๋ธ๋ก์ปค์๊ฒ ๋งก๊ธฐ๋ ๋ ๋ถ๋ฆฌ๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์๋ ์์ต๋๋ค.
๊ทธ๋์ ์ ์ข์๊ฐ์?
์ต์ ๋ฒํจํด ๋ณด๋ค ๋ ๋์จํ๊ฒ ์ด๋ฒคํธ์ ๋ฐํ ๊ฐ์ฒด์ ๊ด์ฐฐ ๊ฐ์ฒด๋ฅผ ๋ถ๋ฆฌํด๋ผ ์ ์๋ค๋ ํฐ ์ฅ์ ์ด ์์ต๋๋ค. ๊ธฐ์กด์ ๋ฐํ ๊ฐ์ฒด์๊ฒ ๋งก๊ฒจ์ง๋ ํ๋ก์๋ค์ ๊ด๋ฆฌ์ ๋ํ ์ฑ ์์ ์ค๊ฐ ๋ธ๋ก์ปค์๊ฒ ๋๊ฒจ์ฃผ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ํ, ๋น๋๊ธฐ ํ๊ฒฝ์์ ๋ฐํ ๊ฐ์ฒด๋ ์ค๊ฐ๋ธ๋ก์ปค์๊ฒ ์ด๋ฒคํธ๋ง ๋์ ธ๋๊ณ ๋ค๋ฅธ ์์ ์ ๋ฐ๋ก ํ ์ ์๊ธฐ ๋๋ฌธ์, ํ์ญ ํจํด์ด ์์ฃผ ํ์ฉ๋๊ธฐ๋ ํฉ๋๋ค.
์ค์ํํธ์ NotificationCenter๊ฐ ํ/์ญ ํจํด๊ณผ ์ ์ฌํ ํํ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์กฐ๋ง๊ฐ ํ ๋ฒ ์ ๋ฆฌํ๋๋ก ํ๊ฒ ์ต๋๋ค!
'๐ฎ ์จ-์์ค > ๐ ๋์์ธํจํด' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote